mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-17 21:25:54 +02:00
Merge pull request #2705 from nxglabs/sync-to-public_repo-31391986146
Merge pull request #2704 from nxglabs/raktima-patch-main-7
This commit is contained in:
Generated
+1966
-2441
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.16.0",
|
||||
"axios": "^1.18.0",
|
||||
"date-fns-tz": "^3.2.0",
|
||||
"dompurify": "^3.4.1",
|
||||
"file-saver": "^2.0.5",
|
||||
@@ -63,7 +63,7 @@
|
||||
"react-quill-new": "^3.8.3",
|
||||
"react-redux": "^9.2.0",
|
||||
"react-rnd": "^10.5.3",
|
||||
"react-router": "^7.14.2",
|
||||
"react-router": "^7.18.2",
|
||||
"react-scrollbars-custom": "^4.1.1",
|
||||
"react-select": "^5.10.2",
|
||||
"react-signature-canvas": "^1.1.0-alpha.2",
|
||||
@@ -128,7 +128,7 @@
|
||||
"autoprefixer": "^10.5.0",
|
||||
"babel-loader": "^9.2.1",
|
||||
"commitizen": "^4.3.1",
|
||||
"concurrently": "^10.0.3",
|
||||
"concurrently": "^10.0.4",
|
||||
"css-loader": "^7.1.4",
|
||||
"daisyui": "^4.12.24",
|
||||
"eslint": "^9.39.4",
|
||||
@@ -147,10 +147,14 @@
|
||||
"vitest": "^4.1.5"
|
||||
},
|
||||
"overrides": {
|
||||
"brace-expansion": ">=2.1.2",
|
||||
"tmp": "$tmp",
|
||||
"react": "$react",
|
||||
"react-dom": "$react-dom",
|
||||
"form-data": ">=4.0.6"
|
||||
"form-data": ">=4.0.6",
|
||||
"js-yaml": "^3.15.0",
|
||||
"undici": "^7.29.0",
|
||||
"fast-uri": "^3.1.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || 22"
|
||||
|
||||
@@ -1597,17 +1597,15 @@
|
||||
"access-code-set": "Zugangscode festgelegt",
|
||||
"access-code-add": "Zugangscode hinzufügen",
|
||||
"access-code-help": "Optionales Geheimnis, das nur dieser Unterzeichner kennt. Vor dem Anzeigen oder Unterschreiben des Dokuments wird die Eingabe verlangt. Geben Sie den Code dem Empfänger auf einem anderen Kanal weiter (Telefon, persönlich).",
|
||||
"access-code-placeholder": "Mindestens 6 Ziffern",
|
||||
"access-code-placeholder": "Mindestens 4 Zeichen",
|
||||
"access-code-clear": "Löschen",
|
||||
"access-code-must-be-numeric": "Der Zugangscode darf nur Ziffern 0-9 enthalten.",
|
||||
"access-code-save": "Speichern",
|
||||
"access-code-required": "Der Absender hat diesem Empfänger einen Zugangscode zugewiesen. Geben Sie ihn ein, um fortzufahren.",
|
||||
"access-code-invalid": "Falscher Zugangscode. Bitte beim Absender nachfragen.",
|
||||
"access-code-too-short": "Der Zugangscode muss mindestens 6 Ziffern lang sein.",
|
||||
"access-code-too-short": "Der Zugangscode muss mindestens 4 Zeichen lang sein.",
|
||||
"access-code-verify": "Zugangscode überprüfen",
|
||||
"access-code-verified": "Zugangscode verifiziert.",
|
||||
"access-code-warning": "Dieser Zugangscode kann nicht geändert oder abgerufen werden, sobald das Dokument versendet wurde.",
|
||||
"copy-access-code": "Zugangscode kopieren",
|
||||
"access-code-upgrade-msg": "Zugangscodes sind nur in kostenpflichtigen Tarifen verfügbar. Aktualisieren Sie Ihren Tarif, um Zugangscodes für Empfänger hinzuzufügen.",
|
||||
"already-copied-to-clipboard": "Bereits in die Zwischenablage kopiert"
|
||||
}
|
||||
|
||||
@@ -1598,17 +1598,17 @@
|
||||
"access-code-set": "Access code set",
|
||||
"access-code-add": "Add access code",
|
||||
"access-code-help": "Optional secret only this signer knows. They will be required to enter it before viewing or signing the document. Share it with the recipient out-of-band (phone, in person).",
|
||||
"access-code-placeholder": "At least 6 digits",
|
||||
"access-code-placeholder": "At least 4 characters",
|
||||
"access-code-clear": "Clear",
|
||||
"access-code-save": "Save",
|
||||
"access-code-required": "This recipient was given an access code by the sender. Enter it to continue.",
|
||||
"access-code-invalid": "Incorrect access code. Please check with the sender.",
|
||||
"access-code-too-short": "Access code must be at least 6 digits.",
|
||||
"access-code-must-be-numeric": "Access code must contain only digits 0-9.",
|
||||
"access-code-too-short": "Access code must be at least 4 characters.",
|
||||
"access-code-verify": "Verify access code",
|
||||
"access-code-verified": "Access code verified.",
|
||||
"access-code-warning": "This access code cannot be changed or retrieved once the document is sent out.",
|
||||
"copy-access-code": "Copy access code",
|
||||
"access-code-upgrade-msg": "Access codes are available on paid plans only. Upgrade your plan to add access codes for recipients.",
|
||||
"show-access-code": "Show access code",
|
||||
"hide-access-code": "Hide access code",
|
||||
"already-copied-to-clipboard": "Already copied to clipboard"
|
||||
}
|
||||
|
||||
@@ -1598,17 +1598,15 @@
|
||||
"access-code-set": "Código de acceso establecido",
|
||||
"access-code-add": "Añadir código de acceso",
|
||||
"access-code-help": "Secreto opcional que solo conoce este firmante. Deberá introducirlo antes de ver o firmar el documento. Compártalo con el destinatario por otro canal (teléfono, en persona).",
|
||||
"access-code-placeholder": "Al menos 6 dígitos",
|
||||
"access-code-placeholder": "Al menos 4 caracteres",
|
||||
"access-code-clear": "Borrar",
|
||||
"access-code-must-be-numeric": "El código de acceso debe contener solo dígitos 0-9.",
|
||||
"access-code-save": "Guardar",
|
||||
"access-code-required": "El remitente asignó un código de acceso a este destinatario. Introdúzcalo para continuar.",
|
||||
"access-code-invalid": "Código de acceso incorrecto. Consulte con el remitente.",
|
||||
"access-code-too-short": "El código de acceso debe tener al menos 6 dígitos.",
|
||||
"access-code-too-short": "El código de acceso debe tener al menos 4 caracteres.",
|
||||
"access-code-verify": "Verificar código de acceso",
|
||||
"access-code-verified": "Código de acceso verificado.",
|
||||
"access-code-warning": "Este código de acceso no se puede cambiar ni recuperar una vez que se envía el documento.",
|
||||
"copy-access-code": "Copiar código de acceso",
|
||||
"access-code-upgrade-msg": "Los códigos de acceso solo están disponibles en planes de pago. Actualice su plan para agregar códigos de acceso a los destinatarios.",
|
||||
"already-copied-to-clipboard": "Ya copiado al portapapeles"
|
||||
}
|
||||
|
||||
@@ -1599,17 +1599,15 @@
|
||||
"access-code-set": "Code d'accès défini",
|
||||
"access-code-add": "Ajouter un code d'accès",
|
||||
"access-code-help": "Secret optionnel connu uniquement de ce signataire. Il devra le saisir avant de voir ou de signer le document. Communiquez-le au destinataire par un autre canal (téléphone, en personne).",
|
||||
"access-code-placeholder": "Au moins 6 chiffres",
|
||||
"access-code-placeholder": "Au moins 4 caractères",
|
||||
"access-code-clear": "Effacer",
|
||||
"access-code-must-be-numeric": "Le code d'accès ne doit contenir que des chiffres 0-9.",
|
||||
"access-code-save": "Enregistrer",
|
||||
"access-code-required": "L'expéditeur a attribué un code d'accès à ce destinataire. Saisissez-le pour continuer.",
|
||||
"access-code-invalid": "Code d'accès incorrect. Veuillez vérifier auprès de l'expéditeur.",
|
||||
"access-code-too-short": "Le code d'accès doit comporter au moins 6 chiffres.",
|
||||
"access-code-too-short": "Le code d'accès doit comporter au moins 4 caractères.",
|
||||
"access-code-verify": "Vérifier le code d'accès",
|
||||
"access-code-verified": "Code d'accès vérifié.",
|
||||
"access-code-warning": "Ce code d'accès ne peut pas être modifié ou récupéré une fois le document envoyé.",
|
||||
"copy-access-code": "Copier le code d'accès",
|
||||
"access-code-upgrade-msg": "Les codes d'accès sont disponibles uniquement dans les forfaits payants. Améliorez votre forfait pour ajouter des codes d'accès aux destinataires.",
|
||||
"already-copied-to-clipboard": "Déjà copié dans le presse-papiers"
|
||||
}
|
||||
|
||||
@@ -1598,17 +1598,15 @@
|
||||
"access-code-set": "एक्सेस कोड सेट किया गया",
|
||||
"access-code-add": "एक्सेस कोड जोड़ें",
|
||||
"access-code-help": "वैकल्पिक गुप्त कोड जो केवल इस हस्ताक्षरकर्ता को पता है। दस्तावेज़ देखने या हस्ताक्षर करने से पहले उन्हें इसे दर्ज करना होगा। इसे प्राप्तकर्ता के साथ किसी अन्य माध्यम (फ़ोन, व्यक्तिगत रूप से) से साझा करें।",
|
||||
"access-code-placeholder": "कम से कम 6 अंक",
|
||||
"access-code-placeholder": "कम से कम 4 अक्षर",
|
||||
"access-code-clear": "साफ़ करें",
|
||||
"access-code-must-be-numeric": "एक्सेस कोड में केवल 0-9 अंक होने चाहिए।",
|
||||
"access-code-save": "सहेजें",
|
||||
"access-code-required": "प्रेषक ने इस प्राप्तकर्ता को एक एक्सेस कोड दिया है। जारी रखने के लिए इसे दर्ज करें।",
|
||||
"access-code-invalid": "गलत एक्सेस कोड। कृपया प्रेषक से जांचें।",
|
||||
"access-code-too-short": "एक्सेस कोड कम से कम 6 अंक का होना चाहिए।",
|
||||
"access-code-too-short": "एक्सेस कोड कम से कम 4 अक्षर का होना चाहिए।",
|
||||
"access-code-verify": "एक्सेस कोड सत्यापित करें",
|
||||
"access-code-verified": "एक्सेस कोड सत्यापित हो गया।",
|
||||
"access-code-warning": "एक बार दस्तावेज़ भेज दिए जाने के बाद इस एक्सेस कोड को बदला या पुनः प्राप्त नहीं किया जा सकता।",
|
||||
"copy-access-code": "एक्सेस कोड कॉपी करें",
|
||||
"access-code-upgrade-msg": "एक्सेस कोड केवल भुगतान योजनाओं पर उपलब्ध हैं। प्राप्तकर्ताओं के लिए एक्सेस कोड जोड़ने के लिए अपनी योजना को अपग्रेड करें।",
|
||||
"already-copied-to-clipboard": "पहले से क्लिपबोर्ड में कॉपी किया गया है"
|
||||
}
|
||||
|
||||
@@ -1598,17 +1598,15 @@
|
||||
"access-code-set": "Codice di accesso impostato",
|
||||
"access-code-add": "Aggiungi codice di accesso",
|
||||
"access-code-help": "Codice segreto facoltativo noto solo a questo firmatario. Dovrà inserirlo prima di visualizzare o firmare il documento. Comunicalo al destinatario tramite un canale alternativo (telefono, di persona).",
|
||||
"access-code-placeholder": "Almeno 6 cifre",
|
||||
"access-code-placeholder": "Almeno 4 caratteri",
|
||||
"access-code-clear": "Cancella",
|
||||
"access-code-must-be-numeric": "Il codice di accesso deve contenere solo cifre 0-9.",
|
||||
"access-code-save": "Salva",
|
||||
"access-code-required": "Il mittente ha assegnato un codice di accesso a questo destinatario. Inseriscilo per continuare.",
|
||||
"access-code-invalid": "Codice di accesso errato. Verifica con il mittente.",
|
||||
"access-code-too-short": "Il codice di accesso deve contenere almeno 6 cifre.",
|
||||
"access-code-too-short": "Il codice di accesso deve contenere almeno 4 caratteri.",
|
||||
"access-code-verify": "Verifica codice di accesso",
|
||||
"access-code-verified": "Codice di accesso verificato.",
|
||||
"access-code-warning": "Questo codice di accesso non può essere modificato o recuperato una volta inviato il documento.",
|
||||
"copy-access-code": "Copia codice di accesso",
|
||||
"access-code-upgrade-msg": "I codici di accesso sono disponibili solo nei piani a pagamento. Aggiorna il tuo piano per aggiungere codici di accesso per i destinatari.",
|
||||
"already-copied-to-clipboard": "Già copiato negli appunti"
|
||||
}
|
||||
|
||||
@@ -1598,17 +1598,15 @@
|
||||
"access-code-set": "접속 코드가 설정됨",
|
||||
"access-code-add": "접속 코드 추가",
|
||||
"access-code-help": "이 서명자만 아는 선택적 비밀번호입니다. 문서를 보거나 서명하기 전에 반드시 입력해야 합니다. 전화 또는 직접 만나서 등 별도의 경로로 수신자에게 전달하세요.",
|
||||
"access-code-placeholder": "6자리 이상 숫자",
|
||||
"access-code-placeholder": "4자 이상",
|
||||
"access-code-clear": "지우기",
|
||||
"access-code-must-be-numeric": "접속 코드는 0-9 숫자만 포함해야 합니다.",
|
||||
"access-code-save": "저장",
|
||||
"access-code-required": "발신자가 이 수신자에게 접속 코드를 지정했습니다. 계속하려면 입력하세요.",
|
||||
"access-code-invalid": "잘못된 접속 코드입니다. 발신자에게 문의하세요.",
|
||||
"access-code-too-short": "접속 코드는 6자리 이상 숫자여야 합니다.",
|
||||
"access-code-too-short": "접속 코드는 4자 이상이어야 합니다.",
|
||||
"access-code-verify": "접속 코드 확인",
|
||||
"access-code-verified": "접속 코드가 확인되었습니다.",
|
||||
"access-code-warning": "문서가 발송된 후에는 이 접속 코드를 변경하거나 검색할 수 없습니다.",
|
||||
"copy-access-code": "접속 코드 복사",
|
||||
"access-code-upgrade-msg": "접속 코드는 유료 요금제에서만 사용할 수 있습니다. 수신자에게 접속 코드를 추가하려면 요금제를 업그레이드하세요.",
|
||||
"already-copied-to-clipboard": "이미 클립보드에 복사됨"
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
|
||||
|
||||
function SignerListPlace(props) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleAddRecipient = () => {
|
||||
props?.setIsAddSigner(true);
|
||||
props.setIsTour && props.setIsTour(false);
|
||||
|
||||
@@ -230,6 +230,355 @@ function PdfRequestFiles(
|
||||
}
|
||||
}, [redirectTimeLeft, isredirectCanceled, redirectUrl]);
|
||||
|
||||
if (!docId || !signerObjId) {
|
||||
throw new Error(t("something-went-wrong-mssg"));
|
||||
}
|
||||
const res = await Parse.Cloud.run("verifyAccessCode", {
|
||||
docId,
|
||||
signerObjId,
|
||||
code
|
||||
});
|
||||
if (res?.verified) {
|
||||
setAccessCodeVerified(true);
|
||||
setAccessCodeRequired(false);
|
||||
return true;
|
||||
}
|
||||
throw new Error(t("access-code-invalid"));
|
||||
} catch (err) {
|
||||
// Re-throw so the modal can render the message inline.
|
||||
throw new Error(
|
||||
err?.message === "Incorrect access code."
|
||||
? t("access-code-invalid")
|
||||
: err?.message || t("access-code-invalid")
|
||||
);
|
||||
} finally {
|
||||
setAccessCodeLoader(false);
|
||||
}
|
||||
};
|
||||
const handleNavigation = () => {
|
||||
window.location.href = subscriptionpath;
|
||||
};
|
||||
async function checkIsSubscribed(extUserId, contactId) {
|
||||
const isGuestSign = isGuestSignFlow || false;
|
||||
const isPublic = props.templateId ? true : false;
|
||||
const res = await fetchSubscription(
|
||||
extUserId,
|
||||
contactId,
|
||||
isGuestSign,
|
||||
isPublic
|
||||
);
|
||||
const plan = res.plan;
|
||||
const billingDate = res?.billingDate;
|
||||
const status = res?.status;
|
||||
|
||||
if (plan === "freeplan") {
|
||||
return true;
|
||||
} else if (billingDate) {
|
||||
if (new Date(billingDate) > new Date()) {
|
||||
if (!isSandbox) {
|
||||
setPlanCode(plan);
|
||||
}
|
||||
setIsSubscribed(true);
|
||||
return true;
|
||||
} else {
|
||||
if (isGuestSign) {
|
||||
setIsSubscriptionExpired(true);
|
||||
} else {
|
||||
handleNavigation(plan);
|
||||
}
|
||||
}
|
||||
} else if (isGuestSign) {
|
||||
if (status) {
|
||||
if (!isSandbox) {
|
||||
setPlanCode(plan);
|
||||
}
|
||||
setIsSubscribed(true);
|
||||
return true;
|
||||
} else {
|
||||
setIsSubscriptionExpired(true);
|
||||
}
|
||||
} else {
|
||||
if (isGuestSign) {
|
||||
setIsSubscriptionExpired(true);
|
||||
} else {
|
||||
handleNavigation(res.plan);
|
||||
}
|
||||
}
|
||||
}
|
||||
// `checkIsSubscribedPublic` this function will check owner subscription and only call in public template flow
|
||||
async function checkIsSubscribedPublic(extUserId) {
|
||||
const isPublic = props.templateId ? true : false;
|
||||
const res = await fetchSubscription(extUserId, "", false, isPublic);
|
||||
const plan = res.plan;
|
||||
const billingDate = res?.billingDate;
|
||||
|
||||
if (plan === "freeplan") {
|
||||
setIsSubscriptionExpired(false);
|
||||
} else if (billingDate) {
|
||||
if (new Date(billingDate) > new Date()) {
|
||||
if (!isSandbox) {
|
||||
setPlanCode(plan);
|
||||
}
|
||||
setIsSubscribed(true);
|
||||
} else {
|
||||
setIsSubscriptionExpired(true);
|
||||
}
|
||||
} else {
|
||||
setIsSubscriptionExpired(true);
|
||||
}
|
||||
}
|
||||
|
||||
//function for get document details for perticular signer with signer'object id
|
||||
//whenever change anything in this function check react/angular packages also in plan js
|
||||
const getTemplateDetails = async () => {
|
||||
try {
|
||||
const params = { templateId: props.templateId, ispublic: true };
|
||||
const templateDeatils = await axios.post(
|
||||
`${localStorage.getItem("baseUrl")}functions/getTemplate`,
|
||||
params,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
sessiontoken: localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
);
|
||||
const documentData = templateDeatils?.data?.result
|
||||
? [templateDeatils?.data?.result]
|
||||
: [];
|
||||
if (documentData && documentData[0]?.error) {
|
||||
props?.setTemplateStatus &&
|
||||
props?.setTemplateStatus({ status: "Invalid" });
|
||||
throw new Error("error: Invalid TemplateId");
|
||||
} else if (documentData && documentData.length > 0) {
|
||||
await checkIsSubscribedPublic(documentData[0]?.ExtUserPtr?.objectId);
|
||||
hideLiveChatWidget(
|
||||
documentData?.[0]?.ExtUserPtr?.TenantId?.HideLiveChatForSigners
|
||||
);
|
||||
if (documentData[0]?.IsPublic) {
|
||||
const prefillImg = await utils?.savePrefillImg(
|
||||
documentData[0]?.Placeholders
|
||||
);
|
||||
if (prefillImg && Array.isArray(prefillImg)) {
|
||||
prefillImg.forEach((img) => {
|
||||
dispatch(setPrefillImg(img));
|
||||
});
|
||||
}
|
||||
// Fetch prefill data from contracts_templateLinks for public mode and merge into local state
|
||||
// so that prefill values saved by the admin are available without modifying the template
|
||||
try {
|
||||
const templateLinksQuery = new Parse.Query(
|
||||
"contracts_templateLinks"
|
||||
);
|
||||
const templatePtr = Parse.Object.extend(
|
||||
"contracts_Template"
|
||||
).createWithoutData(props.templateId);
|
||||
templateLinksQuery.equalTo("TemplatePtr", templatePtr);
|
||||
templateLinksQuery.equalTo("Type", "public");
|
||||
const templateLink = await templateLinksQuery.first();
|
||||
if (templateLink) {
|
||||
const savedPrefillPlaceholders =
|
||||
templateLink.get("Placeholders") || [];
|
||||
|
||||
if (savedPrefillPlaceholders?.length) {
|
||||
// Replace the prefill role in documentData prefill placeholders with the saved prefill details
|
||||
const updatedPlaceholders = documentData[0].Placeholders.map(
|
||||
(ph) => {
|
||||
if (ph.Role === "prefill") {
|
||||
return {
|
||||
...ph,
|
||||
placeHolder: savedPrefillPlaceholders // ✅ only update this field
|
||||
};
|
||||
}
|
||||
return ph;
|
||||
}
|
||||
);
|
||||
|
||||
documentData[0] = {
|
||||
...documentData[0],
|
||||
Placeholders: updatedPlaceholders
|
||||
};
|
||||
|
||||
// Re-run savePrefillImg with the updated placeholders so image widgets are loaded correctly
|
||||
const updatedPrefillImg = await utils?.savePrefillImg(
|
||||
documentData[0]?.Placeholders
|
||||
);
|
||||
|
||||
if (updatedPrefillImg && Array.isArray(updatedPrefillImg)) {
|
||||
updatedPrefillImg.forEach((img) => {
|
||||
dispatch(setPrefillImg(img));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error fetching templateLinks for public:", e);
|
||||
}
|
||||
const appname =
|
||||
documentData?.[0]?.ExtUserPtr?.TenantId?.WhiteLabelAppName ||
|
||||
appName;
|
||||
localStorage.setItem("appname", appname);
|
||||
//handle condition when someone use plan js then setTemplateStatus is not supporting
|
||||
props?.setTemplateStatus &&
|
||||
props?.setTemplateStatus({ status: "Success" });
|
||||
const url =
|
||||
documentData[0] &&
|
||||
(documentData[0]?.SignedUrl || documentData[0]?.URL);
|
||||
setSendInOrder(documentData[0]?.SendinOrder || false);
|
||||
setExtUserId(documentData[0]?.ExtUserPtr?.objectId);
|
||||
setOwner(documentData?.[0]?.ExtUserPtr);
|
||||
// Collect all assigned widget IDs. If modification is enabled, the user can only add or modify new widgets—not the ones already assigned.
|
||||
if (documentData[0]?.AllowModifications) {
|
||||
const removePrefill = documentData[0]?.Placeholders.filter(
|
||||
(x) => x.Role !== "prefill"
|
||||
);
|
||||
const firstRolePH = removePrefill[0];
|
||||
const widgetId = firstRolePH.placeHolder?.flatMap((page) => {
|
||||
return page.pos.map((item) => item.key);
|
||||
});
|
||||
setAssignedWidgetId(widgetId);
|
||||
}
|
||||
if (url) {
|
||||
const base64Pdf = await getBase64FromUrl(url);
|
||||
if (base64Pdf) {
|
||||
setPdfBase64Url(base64Pdf);
|
||||
}
|
||||
} else {
|
||||
setHandleError(t("something-went-wrong-mssg"));
|
||||
}
|
||||
//handle allowed signature type
|
||||
const userSignatureType =
|
||||
documentData?.[0]?.ExtUserPtr?.SignatureType || signatureTypes;
|
||||
const docSignTypes =
|
||||
documentData?.[0]?.SignatureType || userSignatureType;
|
||||
setSignatureType(docSignTypes);
|
||||
const removePrefill =
|
||||
documentData[0]?.Placeholders.filter((x) => x.Role !== "prefill") ||
|
||||
[];
|
||||
const isAttachAllSigner =
|
||||
removePrefill?.length > 0 &&
|
||||
removePrefill?.every(
|
||||
(data) => data?.signerObjId && data?.Role !== "prefill"
|
||||
);
|
||||
const isEnableOTP = documentData?.[0]?.IsEnableOTP || false;
|
||||
if (isAttachAllSigner) {
|
||||
if (isEnableOTP) {
|
||||
setIsPublicTemplate(true);
|
||||
} else {
|
||||
setCurrentSigner(true);
|
||||
setSignerObjectId(documentData?.[0]?.Signers?.[0]?.objectId);
|
||||
}
|
||||
} else {
|
||||
setIsPublicTemplate(true);
|
||||
}
|
||||
|
||||
setUniqueId(removePrefill[0]?.Id);
|
||||
let placeholdersOrSigners = [];
|
||||
for (const placeholder of removePrefill) {
|
||||
//`emailExist` variable to handle condition for quick send flow and show unsigned signers list
|
||||
const signerIdExist = placeholder?.signerObjId;
|
||||
if (signerIdExist) {
|
||||
const getSignerData = documentData[0]?.Signers?.find(
|
||||
(data) => data.objectId === placeholder?.signerObjId
|
||||
);
|
||||
placeholdersOrSigners.push(getSignerData);
|
||||
} else {
|
||||
placeholdersOrSigners.push(placeholder);
|
||||
}
|
||||
}
|
||||
const getVacantRole = documentData[0]?.Placeholders?.filter(
|
||||
(x) => !x?.signerObjId && x.Role !== "prefill"
|
||||
);
|
||||
if (getVacantRole?.length > 0) {
|
||||
setVacantRole(getVacantRole);
|
||||
setFormData(
|
||||
getVacantRole.map(() => ({
|
||||
name: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
id: ""
|
||||
}))
|
||||
);
|
||||
}
|
||||
if (removePrefill && removePrefill.length > 0) {
|
||||
//check first role attached signer or not
|
||||
const getfirstSignerObjId = removePrefill[0]?.signerObjId;
|
||||
//save isSignerFirstRole true if first role attached signer
|
||||
if (getfirstSignerObjId) {
|
||||
setIsSignerFirstRole(true);
|
||||
}
|
||||
}
|
||||
setUnSignedSigners(placeholdersOrSigners);
|
||||
setPdfDetails(documentData);
|
||||
setSignerPos(
|
||||
updateDateWidgetsRes(documentData[0], removePrefill[0]?.Id)
|
||||
);
|
||||
setIsLoading({ isLoad: false });
|
||||
} else {
|
||||
props?.setTemplateStatus &&
|
||||
props?.setTemplateStatus({ status: "Private" });
|
||||
setIsLoading({ isLoad: false });
|
||||
// setHandleError(t("something-went-wrong-mssg"));
|
||||
setHandleError(t("this-template-is-not-public"));
|
||||
console.error("error: TemplateId is not public");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
props?.setTemplateStatus &&
|
||||
props?.setTemplateStatus({ status: "Invalid" });
|
||||
setIsLoading({ isLoad: false });
|
||||
setHandleError(t("invalid-templateid"));
|
||||
console.error("error: Invalid TemplateId");
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
setIsLoading({ isLoad: false });
|
||||
if (err?.response?.data?.code === 101) {
|
||||
setHandleError(t("error-template"));
|
||||
} else if (err?.message?.includes("Invalid")) {
|
||||
setHandleError(t("invalid-templateid"));
|
||||
} else {
|
||||
setHandleError(t("something-went-wrong-mssg"));
|
||||
}
|
||||
console.error("error: Invalid TemplateId", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const addsigner = async (contact) => {
|
||||
try {
|
||||
const baseURL = localStorage.getItem("baseUrl");
|
||||
const url = `${baseURL}functions/publicsavecontact`;
|
||||
const data = contact;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId")
|
||||
};
|
||||
await axios.post(url, data, { headers });
|
||||
} catch (err) {
|
||||
console.log("Err", err);
|
||||
setHandleError(t("something-went-wrong-mssg"));
|
||||
}
|
||||
};
|
||||
|
||||
// `checkIfAlreadySubmitted` function will check whether signer already submitted the offline signed document to avoid multiple submission for same document by same signer.
|
||||
const checkIfAlreadySubmitted = async (documentId, contactId) => {
|
||||
try {
|
||||
const { offlineSigned } = await Parse.Cloud.run(
|
||||
"checkofflinesubmission",
|
||||
{ documentId, contactId }
|
||||
);
|
||||
if (offlineSigned) {
|
||||
setHandleError(t("offline-already-submitted-body"));
|
||||
return true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error checking offline submission:", error);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
const fetchTenantDetails = async (contactId) => {
|
||||
const user = JSON.parse(
|
||||
@@ -1423,6 +1772,151 @@ function PdfRequestFiles(
|
||||
closeTour();
|
||||
setIsReqSignTourDisabled(true);
|
||||
};
|
||||
}
|
||||
setIsUiLoading(false);
|
||||
} catch (e) {
|
||||
console.log("e", e);
|
||||
if (
|
||||
e?.response?.data?.error === "Insufficient Credit" ||
|
||||
e?.response?.data?.error === "Plan expired"
|
||||
) {
|
||||
handleCloseOtp();
|
||||
setIsAlert({
|
||||
title: t("insufficient-credits-title"),
|
||||
isShow: true,
|
||||
alertMessage: t("insufficient-credits-mssg", { appName })
|
||||
});
|
||||
} else {
|
||||
handleCloseOtp();
|
||||
setIsAlert({
|
||||
title: "Error",
|
||||
isShow: true,
|
||||
alertMessage: t("something-went-wrong-mssg")
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleInputChange = (e) => {
|
||||
let { name, value } = e.target;
|
||||
const updatedForm = [...formData];
|
||||
if (name === "email") {
|
||||
value = value?.toLowerCase()?.replace(/\s/g, "");
|
||||
}
|
||||
updatedForm[currentIndex] = {
|
||||
...updatedForm[currentIndex],
|
||||
[name]: value,
|
||||
id: vacantRole[currentIndex]?.Id
|
||||
};
|
||||
setFormData(updatedForm);
|
||||
};
|
||||
const SendOtp = async (app, email, isLoad) => {
|
||||
if (isLoad) {
|
||||
setLoading(true);
|
||||
setIsOtp(true);
|
||||
}
|
||||
const appName = app || localStorage.getItem("appname") || "OpenSign™";
|
||||
try {
|
||||
const params = {
|
||||
email: email,
|
||||
appName: appName
|
||||
};
|
||||
const Otp = await axios.post(
|
||||
`${localStorage.getItem("baseUrl")}/functions/SendOTPMailV1`,
|
||||
params,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId")
|
||||
}
|
||||
}
|
||||
);
|
||||
if (Otp) {
|
||||
setIsOtp(true);
|
||||
setLoading(false);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("error in verify otp in public-sign", error);
|
||||
setIsAlert({
|
||||
title: "Error",
|
||||
isShow: true,
|
||||
alertMessage: t("something-went-wrong-mssg")
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//verify OTP send on via email
|
||||
const VerifyOTP = async (e) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
const serverUrl =
|
||||
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
|
||||
const parseId =
|
||||
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
|
||||
if (otp) {
|
||||
try {
|
||||
let url = `${serverUrl}/functions/AuthLoginAsMail`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": parseId
|
||||
};
|
||||
let contact;
|
||||
if (isSignerFirstRole) {
|
||||
const firstSigner = pdfDetails?.[0]?.Signers?.[0];
|
||||
contact = { email: firstSigner.Email, name: firstSigner.Name };
|
||||
} else {
|
||||
contact = formData[0];
|
||||
}
|
||||
|
||||
let body = { email: contact.email, otp: otp };
|
||||
let user = await axios.post(url, body, { headers: headers });
|
||||
if (user.data.result === "Invalid Otp") {
|
||||
alert(t("invalid-otp"));
|
||||
setLoading(false);
|
||||
} else if (user.data.result === "user not found!") {
|
||||
alert(t("user-not-found"));
|
||||
setLoading(false);
|
||||
} else {
|
||||
let _user = user.data.result;
|
||||
const parseId = localStorage.getItem("parseAppId");
|
||||
if (_user) {
|
||||
localStorage.setItem("accesstoken", _user?.sessionToken);
|
||||
localStorage.setItem("UserInformation", JSON.stringify(_user));
|
||||
localStorage.setItem(
|
||||
`Parse/${parseId}/currentUser`,
|
||||
JSON.stringify(_user)
|
||||
);
|
||||
}
|
||||
await Parse.User.become(_user.sessionToken);
|
||||
const contractUserDetails = await contractUsers();
|
||||
if (contractUserDetails && contractUserDetails.length > 0) {
|
||||
localStorage.setItem(
|
||||
"Extand_Class",
|
||||
JSON.stringify(contractUserDetails)
|
||||
);
|
||||
}
|
||||
setLoading(false);
|
||||
setIsLoading({ isLoad: false });
|
||||
setIsPublicContact(false);
|
||||
setIsPublicTemplate(false);
|
||||
const removePrefill = signerPos.filter((x) => x.Role !== "prefill");
|
||||
const getSignerObjId = removePrefill[0]?.signerObjId;
|
||||
setSignerObjectId(getSignerObjId);
|
||||
setCurrentSigner(true);
|
||||
setSignerPos(updateDateWidgetsRes(pdfDetails[0], getSignerObjId));
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("err ", error);
|
||||
}
|
||||
} else {
|
||||
alert(t("enter-otp-alert"));
|
||||
}
|
||||
};
|
||||
const handleCloseOtp = () => {
|
||||
setIsPublicContact(false);
|
||||
setLoading(false);
|
||||
setIsOtp(false);
|
||||
setOtp();
|
||||
};
|
||||
|
||||
const clickOnZoomIn = () => {
|
||||
onClickZoomIn(scale, setScale, scrollRef);
|
||||
|
||||
Generated
+587
-601
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,7 @@
|
||||
"@signpdf/placeholder-pdf-lib": "^3.3.0",
|
||||
"@signpdf/signer-p12": "^3.3.0",
|
||||
"@signpdf/signpdf": "^3.3.0",
|
||||
"axios": "^1.16.0",
|
||||
"axios": "^1.18.0",
|
||||
"coherentpdf": "^2.5.5",
|
||||
"cors": "^2.8.6",
|
||||
"date-fns-tz": "^3.2.0",
|
||||
@@ -40,14 +40,14 @@
|
||||
"mailgun.js": "^13.0.0",
|
||||
"moment": "^2.30.1",
|
||||
"mongodb": "^7.2.0",
|
||||
"multer": "^2.2.0",
|
||||
"multer": "^2.1.1",
|
||||
"multer-s3": "^3.0.1",
|
||||
"node-forge": "^1.3.3",
|
||||
"nodemailer": "^8.0.7",
|
||||
"p-limit": "^7.3.0",
|
||||
"parse": "^8.6.0",
|
||||
"parse": "^8.1.0",
|
||||
"parse-dbtool": "^1.2.0",
|
||||
"parse-server": "^8.6.84",
|
||||
"parse-server": "^8.6.77",
|
||||
"parse-server-api-mail-adapter": "^5.0.5",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"posthog-node": "^5.21.2",
|
||||
@@ -68,13 +68,20 @@
|
||||
"prettier": "^3.8.3"
|
||||
},
|
||||
"overrides": {
|
||||
"brace-expansion": ">=2.1.2",
|
||||
"ws": "$ws",
|
||||
"parse": "$parse",
|
||||
"form-data": "$form-data",
|
||||
"@parse/push-adapter": "$@parse/push-adapter",
|
||||
"fast-xml-builder": "1.2.0",
|
||||
"protobufjs": ">=7.6.3",
|
||||
"tmp": ">=0.2.7"
|
||||
"tmp": ">=0.2.7",
|
||||
"decompress": "npm:@xhmikosr/decompress@^11.1.4",
|
||||
"tar": "^7.5.19",
|
||||
"websocket-driver": ">=0.7.5",
|
||||
"js-yaml": "^3.15.0",
|
||||
"lodash": "^4.18.0",
|
||||
"undici": "^7.29.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || 22"
|
||||
|
||||
Reference in New Issue
Block a user