From 3599fbee21cb5d2140a5e646938a36d330fe3275 Mon Sep 17 00:00:00 2001 From: prafull-opensignlabs Date: Mon, 29 Apr 2024 17:38:25 +0530 Subject: [PATCH] fix: changes in certificate --- apps/OpenSign/src/constant/Utils.js | 3 +- apps/OpenSign/src/pages/PdfRequestFiles.js | 7 +- apps/OpenSign/src/pages/SignyourselfPdf.js | 11 +- .../cloud/parsefunction/callWebhook.js | 41 +- .../parsefunction/pdf/GenerateCertificate.js | 406 ++++++++++++++-- .../cloud/parsefunction/pdf/PDF.min.js | 432 ++++++++---------- 6 files changed, 612 insertions(+), 288 deletions(-) diff --git a/apps/OpenSign/src/constant/Utils.js b/apps/OpenSign/src/constant/Utils.js index 67b399d03..1f28db8f1 100644 --- a/apps/OpenSign/src/constant/Utils.js +++ b/apps/OpenSign/src/constant/Utils.js @@ -572,7 +572,8 @@ export const signPdfFun = async ( headers: { "Content-Type": "application/json", "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - sessionToken: localStorage.getItem("accesstoken") + // sessionToken: localStorage.getItem("accesstoken") + "X-Parse-Session-Token": localStorage.getItem("accesstoken") } }) .then((Listdata) => { diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 4f433ba2f..435d613f1 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -271,6 +271,7 @@ function PdfRequestFiles() { ) { const params = { event: "viewed", + contactId: currUserId, body: { objectId: documentData?.[0].objectId, file: documentData?.[0]?.SignedUrl || documentData?.[0]?.URL, @@ -1139,9 +1140,9 @@ function PdfRequestFiles() { isDecline.currnt === "Sure" ? "Are you sure want to decline this document ?" : isDecline.currnt === "YouDeclined" - ? "You have declined this document!" - : isDecline.currnt === "another" && - "You can not sign this document as it has been declined/revoked." + ? "You have declined this document!" + : isDecline.currnt === "another" && + "You can not sign this document as it has been declined/revoked." } footerMessage={isDecline.currnt === "Sure"} declineDoc={declineDoc} diff --git a/apps/OpenSign/src/pages/SignyourselfPdf.js b/apps/OpenSign/src/pages/SignyourselfPdf.js index b14c6934c..d3f3c9aa8 100644 --- a/apps/OpenSign/src/pages/SignyourselfPdf.js +++ b/apps/OpenSign/src/pages/SignyourselfPdf.js @@ -443,13 +443,13 @@ function SignYourSelf() { Width: widgetTypeExist ? calculateInitialWidthHeight(dragTypeValue, widgetValue).getWidth : dragTypeValue === "initials" - ? defaultWidthHeight(dragTypeValue).width - : "", + ? defaultWidthHeight(dragTypeValue).width + : "", Height: widgetTypeExist ? calculateInitialWidthHeight(dragTypeValue, widgetValue).getHeight : dragTypeValue === "initials" - ? defaultWidthHeight(dragTypeValue).height - : "", + ? defaultWidthHeight(dragTypeValue).height + : "", options: addWidgetOptions(dragTypeValue) }; @@ -626,7 +626,8 @@ function SignYourSelf() { headers: { "Content-Type": "application/json", "X-Parse-Application-Id": localStorage.getItem("parseAppId"), - sessionToken: localStorage.getItem("accesstoken") + // sessionToken: localStorage.getItem("accesstoken") + "X-Parse-Session-Token": localStorage.getItem("accesstoken") } }) .then((Listdata) => { diff --git a/apps/OpenSignServer/cloud/parsefunction/callWebhook.js b/apps/OpenSignServer/cloud/parsefunction/callWebhook.js index 7e2fa4056..a9d127c36 100644 --- a/apps/OpenSignServer/cloud/parsefunction/callWebhook.js +++ b/apps/OpenSignServer/cloud/parsefunction/callWebhook.js @@ -2,6 +2,8 @@ import axios from 'axios'; export default async function callWebhook(request) { const event = request.params.event; const body = request.params.body; + const docId = body.objectId; + const contactId = request.params.contactId; const serverUrl = process.env.SERVER_URL; const appId = process.env.APP_ID; const userRes = await axios.get(serverUrl + '/users/me', { @@ -13,6 +15,39 @@ export default async function callWebhook(request) { const userId = userRes.data && userRes.data.objectId; if (userId) { + if (event === 'viewed' && contactId) { + const docQuery = new Parse.Query('contracts_Document'); + const res = await docQuery.get(docId, { useMasterKey: true }); + if (res) { + const _res = res.toJSON(); + const userPtr = { + __type: 'Pointer', + className: 'contracts_Contactbook', + objectId: contactId, + }; + const date = new Date().toISOString(); + const obj = { + UserPtr: userPtr, + SignedUrl: _res.SignedUrl, + Activity: 'Viewed', + ipAddress: request.headers['x-real-ip'], + ViewedOn: date, + }; + const isUserExist = _res?.AuditTrail?.some( + x => x.UserPtr.objectId === contactId && x?.ViewedOn + ); + if (!isUserExist) { + const updateDoc = new Parse.Object('contracts_Document'); + updateDoc.id = res.id; + if (_res?.AuditTrail && _res?.AuditTrail?.length > 0) { + updateDoc.set('AuditTrail', [..._res?.AuditTrail, obj]); + } else { + updateDoc.set('AuditTrail', [obj]); + } + await updateDoc.save(null, { useMasterKey: true }); + } + } + } const extendcls = new Parse.Query('contracts_Users'); extendcls.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId }); const res = await extendcls.first({ useMasterKey: true }); @@ -39,11 +74,11 @@ export default async function callWebhook(request) { }); webhook.save(null, { useMasterKey: true }); } catch (err) { - console.log('err save in contracts_Webhook', err); + console.log('err save in contracts_Webhook', err.message); } }) .catch(err => { - console.log('Err send data to webhook', err); + console.log('Err send data to webhook', err.message); try { const webhook = new Parse.Object('contracts_Webhook'); webhook.set('Log', err?.status); @@ -54,7 +89,7 @@ export default async function callWebhook(request) { }); webhook.save(null, { useMasterKey: true }); } catch (err) { - console.log('err save in contracts_Webhook', err); + console.log('err save in contracts_Webhook', err.message); } }); } diff --git a/apps/OpenSignServer/cloud/parsefunction/pdf/GenerateCertificate.js b/apps/OpenSignServer/cloud/parsefunction/pdf/GenerateCertificate.js index 2b9b7625f..739ea3a9a 100644 --- a/apps/OpenSignServer/cloud/parsefunction/pdf/GenerateCertificate.js +++ b/apps/OpenSignServer/cloud/parsefunction/pdf/GenerateCertificate.js @@ -17,21 +17,36 @@ export default async function GenerateCertificate(docDetails) { const text = 14; const textKeyColor = rgb(0.12, 0.12, 0.12); const textValueColor = rgb(0.3, 0.3, 0.3); - const completedAt = new Date(docDetails.updatedAt); + const completedAt = new Date(); const completedUTCtime = completedAt.toUTCString(); const signersCount = docDetails?.Signers?.length || 1; - const createdAt = new Date(); - const createdUTCTime = createdAt.toUTCString(); - const createDate = 'Generated On ' + createdUTCTime; + const generateAt = new Date(); + const generatedUTCTime = generateAt.toUTCString(); + const generatedOn = 'Generated On ' + generatedUTCTime; const company = docDetails?.ExtUserPtr?.Company || ''; const auditTrail = docDetails.AuditTrail?.length > 1 ? docDetails.AuditTrail.map(x => { const data = docDetails.Signers.find(y => y.objectId === x.UserPtr.objectId); - return { ...data, ipAddress: x.ipAddress }; + return { + ...data, + ipAddress: x.ipAddress, + SignedOn: x?.SignedOn || generatedUTCTime, + ViewedOn: x?.ViewedOn || generatedUTCTime, + Signature: x?.Signature || '', + }; }) - : [{ ...docDetails.ExtUserPtr, ipAddress: docDetails?.AuditTrail[0].ipAddress }]; + : [ + { + ...docDetails.ExtUserPtr, + ipAddress: docDetails?.AuditTrail[0].ipAddress, + SignedOn: docDetails?.AuditTrail[0]?.SignedOn || generatedUTCTime, + ViewedOn: docDetails?.AuditTrail[0]?.ViewedOn || generatedUTCTime, + Signature: docDetails?.AuditTrail[0]?.Signature || '', + }, + ]; + const half = width / 2; // Draw a border page.drawRectangle({ x: startX, @@ -48,7 +63,7 @@ export default async function GenerateCertificate(docDetails) { height: 25, }); - page.drawText(createDate, { + page.drawText(generatedOn, { x: 320, y: 810, size: 12, @@ -127,8 +142,7 @@ export default async function GenerateCertificate(docDetails) { font: timesRomanFont, color: textValueColor, }); - - page.drawText('Completed on :', { + page.drawText('Created on :', { x: 30, y: 625, size: text, @@ -136,15 +150,14 @@ export default async function GenerateCertificate(docDetails) { color: textKeyColor, }); - page.drawText(`${completedUTCtime}`, { - x: 120, + page.drawText(`${new Date(docDetails.createdAt).toUTCString()}`, { + x: 105, y: 625, size: text, font: timesRomanFont, color: textValueColor, }); - - page.drawText('Signers :', { + page.drawText('Completed on :', { x: 30, y: 605, size: text, @@ -152,35 +165,102 @@ export default async function GenerateCertificate(docDetails) { color: textKeyColor, }); + page.drawText(`${completedUTCtime}`, { + x: 125, + y: 605, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + page.drawText('Signers :', { + x: 30, + y: 585, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + page.drawText(`${signersCount}`, { x: 80, - y: 605, + y: 585, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + page.drawText('Document originator', { + x: 30, + y: 565, + size: 17, + font: timesRomanFont, + color: titleColor, + }); + page.drawText('Name :', { + x: 60, + y: 545, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + page.drawText(`${docDetails.ExtUserPtr.Name}`, { + x: 105, + y: 545, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + page.drawText('Email :', { + x: 60, + y: 525, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + page.drawText(`${docDetails.ExtUserPtr.Email}`, { + x: 105, + y: 525, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + page.drawText('IP address :', { + x: 60, + y: 505, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + page.drawText(`152.58.21.622`, { + x: 130, + y: 505, size: text, font: timesRomanFont, color: textValueColor, }); page.drawLine({ - start: { x: 30, y: 565 }, - end: { x: width - 30, y: 565 }, + start: { x: 30, y: 495 }, + end: { x: width - 30, y: 495 }, color: rgb(0.12, 0.12, 0.12), thickness: 0.5, }); - page.drawText('Recipients', { - x: 30, - y: 575, - size: subtitle, - font: timesRomanFont, - color: titleColor, - }); - let yPosition1 = 550; - let yPosition2 = 530; - let yPosition3 = 510; - let yPosition4 = 500; - auditTrail.forEach(x => { - page.drawText('Name :', { + let yPosition1 = 475; + let yPosition2 = 455; + let yPosition3 = 435; + let yPosition4 = 415; + let yPosition5 = 395; + let yPosition6 = 360; + auditTrail.slice(0, 3).forEach(async (x, i) => { + const embedPng = x.signature ? await pdfDoc.embedPng(x.signature) : ''; + page.drawText(`Signer ${i + 1}`, { x: 30, y: yPosition1, + size: subtitle, + font: timesRomanFont, + color: titleColor, + }); + page.drawText('Name :', { + x: 30, + y: yPosition2, size: text, font: timesRomanFont, color: textKeyColor, @@ -188,7 +268,23 @@ export default async function GenerateCertificate(docDetails) { page.drawText(x?.Name, { x: 75, - y: yPosition1, + y: yPosition2, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + + page.drawText('Viewed on :', { + x: half, + y: yPosition2, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + page.drawText(`${new Date(x.SignedOn).toUTCString()}`, { + x: half + 75, + y: yPosition2, size: text, font: timesRomanFont, color: textValueColor, @@ -196,7 +292,7 @@ export default async function GenerateCertificate(docDetails) { page.drawText('Email :', { x: 30, - y: yPosition2, + y: yPosition3, size: text, font: timesRomanFont, color: textKeyColor, @@ -204,41 +300,271 @@ export default async function GenerateCertificate(docDetails) { page.drawText(x?.Email, { x: 75, - y: yPosition2, + y: yPosition3, size: text, font: timesRomanFont, color: textValueColor, }); - page.drawText('Accessed from :', { - x: 30, + page.drawText('Signed on :', { + x: half, y: yPosition3, size: text, font: timesRomanFont, color: textKeyColor, }); - page.drawText(x?.ipAddress, { - x: 125, + page.drawText(`${new Date(x.SignedOn).toUTCString()}`, { + x: half + 70, y: yPosition3, size: text, font: timesRomanFont, color: textValueColor, }); + page.drawText('IP address :', { + x: 30, + y: yPosition4, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + page.drawText(x?.ipAddress, { + x: 100, + y: yPosition4, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + page.drawText('Security level :', { + x: half, + y: yPosition4, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + page.drawText(`Email, OTP Auth`, { + x: half + 90, + y: yPosition4, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + + page.drawText('Signature :', { + x: 30, + y: yPosition5, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + page.drawRectangle({ + x: 98, + y: yPosition5 - 27, + width: 104, + height: 44, + borderColor: rgb(0.22, 0.18, 0.47), + borderWidth: 1, + }); + if (embedPng) { + page.drawImage(embedPng, { + x: 100, + y: yPosition5 - 25, + width: 100, + height: 40, + }); + } page.drawLine({ - start: { x: 30, y: yPosition4 }, - end: { x: width - 30, y: yPosition4 }, + start: { x: 30, y: yPosition6 }, + end: { x: width - 30, y: yPosition6 }, color: rgb(0.12, 0.12, 0.12), thickness: 0.5, }); - yPosition1 = yPosition4 - 20; + yPosition1 = yPosition6 - 20; yPosition2 = yPosition1 - 20; yPosition3 = yPosition2 - 20; - yPosition4 = yPosition4 - 70; + yPosition4 = yPosition3 - 20; + yPosition5 = yPosition4 - 20; + yPosition6 = yPosition6 - 140; }); + if (auditTrail.length > 3) { + let currentPageIndex = 1; + let currentPage = page; + auditTrail.slice(3).forEach(async (x, i) => { + const embedPng = x.signature ? await pdfDoc.embedPng(x.signature) : ''; + + // Calculate remaining space on current page + const remainingSpace = yPosition6; + + // If there's not enough space for the next entry, create a new page + if (remainingSpace < 90) { + // Adjust the value as needed + currentPageIndex++; + currentPage = pdfDoc.addPage(); + currentPage.drawRectangle({ + x: startX, + y: startY, + width: width - 2 * startX, + height: height - 2 * startY, + borderColor: borderColor, + borderWidth: 1, + }); + yPosition1 = currentPage.getHeight() - 40; + yPosition2 = yPosition1 - 20; + yPosition3 = yPosition2 - 20; + yPosition4 = yPosition3 - 20; + yPosition5 = yPosition4 - 20; + yPosition6 = currentPage.getHeight() - 160; + } + + currentPage.drawText(`Signer ${4 + i}`, { + x: 30, + y: yPosition1, + size: subtitle, + font: timesRomanFont, + color: titleColor, + }); + currentPage.drawText('Name :', { + x: 30, + y: yPosition2, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + currentPage.drawText(x?.Name, { + x: 75, + y: yPosition2, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + + currentPage.drawText('Viewed on :', { + x: half, + y: yPosition2, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + currentPage.drawText(`${new Date(x.SignedOn).toUTCString()}`, { + x: half + 75, + y: yPosition2, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + + currentPage.drawText('Email :', { + x: 30, + y: yPosition3, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + currentPage.drawText(x?.Email, { + x: 75, + y: yPosition3, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + + currentPage.drawText('Signed on :', { + x: half, + y: yPosition3, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + currentPage.drawText(`${new Date(x.SignedOn).toUTCString()}`, { + x: half + 70, + y: yPosition3, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + + currentPage.drawText('IP address :', { + x: 30, + y: yPosition4, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + currentPage.drawText(x?.ipAddress, { + x: 100, + y: yPosition4, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + currentPage.drawText('Security level :', { + x: half, + y: yPosition4, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + + currentPage.drawText(`Email, OTP Auth`, { + x: half + 90, + y: yPosition4, + size: text, + font: timesRomanFont, + color: textValueColor, + }); + + currentPage.drawText('Signature :', { + x: 30, + y: yPosition5, + size: text, + font: timesRomanFont, + color: textKeyColor, + }); + currentPage.drawRectangle({ + x: 98, + y: yPosition5 - 27, + width: 104, + height: 44, + borderColor: rgb(0.22, 0.18, 0.47), + borderWidth: 1, + }); + if (embedPng) { + currentPage.drawImage(embedPng, { + x: 100, + y: yPosition5 - 25, + width: 100, + height: 40, + }); + } + + currentPage.drawLine({ + start: { x: 30, y: yPosition6 }, + end: { x: width - 30, y: yPosition6 }, + color: rgb(0.12, 0.12, 0.12), + thickness: 0.5, + }); + + // Update y positions for the next entry + yPosition1 = yPosition6 - 20; + yPosition2 = yPosition1 - 20; + yPosition3 = yPosition2 - 20; + yPosition4 = yPosition3 - 20; + yPosition5 = yPosition4 - 20; + yPosition6 = yPosition6 - 140; + }); + } + const pdfBytes = await pdfDoc.save(); return pdfBytes; } diff --git a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js index 6b249f797..a84ceb9a4 100644 --- a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js +++ b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js @@ -8,85 +8,96 @@ import GenerateCertificate from './GenerateCertificate.js'; const serverUrl = process.env.SERVER_URL, APPID = process.env.APP_ID, masterKEY = process.env.MASTER_KEY; -async function uploadFile(e, a) { +async function uploadFile(e, t) { try { - var t = fs.readFileSync(a), - s = new Parse.File(e, [...t], 'application/pdf'), - r = (await s.save({ useMasterKey: !0 }), s.url()); - return { imageUrl: r }; + var a = fs.readFileSync(t), + r = new Parse.File(e, [...a], 'application/pdf'), + i = (await r.save({ useMasterKey: !0 }), r.url()); + return { imageUrl: i }; } catch (e) { - console.log('Err ', e), fs.unlinkSync(a); + console.log('Err ', e), fs.unlinkSync(t); } } -async function updateDoc(t, s, r, i, o, n) { +async function updateDoc(a, r, i, s, o, n, l) { try { - var l = { - UserPtr: { __type: 'Pointer', className: n, objectId: r }, - SignedUrl: s, - Activity: 'Signed', - ipAddress: i, - }; + var c, + d, + p = { + UserPtr: { __type: 'Pointer', className: n, objectId: i }, + SignedUrl: r, + Activity: 'Signed', + ipAddress: s, + SignedOn: new Date(), + Signature: l, + }; let e; - var d = (e = o.AuditTrail && 0 < o.AuditTrail.length ? [...o.AuditTrail, l] : [l]).filter( - e => 'Signed' === e.Activity - ); - let a = !1; - !((o.Signers && 0 < o.Signers.length && d.length !== o.Signers.length) || !(a = !0)); - var c = { SignedUrl: s, AuditTrail: e, IsCompleted: a }; - await axios.put(serverUrl + '/classes/contracts_Document/' + t, c, { + var m = (e = + o.AuditTrail && 0 < o.AuditTrail.length + ? (-1 !== + (d = (c = JSON.parse(JSON.stringify(o.AuditTrail))).findIndex( + e => e.UserPtr.objectId === i && 'Created' !== e.Activity + )) + ? (c[d] = { ...c[d], ...p }) + : c.push(p), + c) + : [p]).filter(e => 'Signed' === e.Activity); + let t = !1; + !((o.Signers && 0 < o.Signers.length && m.length !== o.Signers.length) || !(t = !0)); + var g = { SignedUrl: r, AuditTrail: e, IsCompleted: t }; + await axios.put(serverUrl + '/classes/contracts_Document/' + a, g, { headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY, }, }); - return { isCompleted: a, message: 'success', AuditTrail: e }; + return { isCompleted: t, message: 'success', AuditTrail: e }; } catch (e) { return console.log('update doc err ', e), 'err'; } } async function sendCompletedMail(e) { - var a = e.url, - t = e.doc, - s = e.doc.ExtUserPtr, - r = t.Name, - i = s.Email; - let o = `Document "${r}" has been signed by all parties`, + var t = e.url, + a = e.doc, + r = e.doc.ExtUserPtr, + i = a.Name, + s = r.Email; + let o = `Document "${i}" has been signed by all parties`, n = "

Document signed successfully

All parties have successfully signed the document " + - `"${r}"` + + `"${i}"` + '. Kindly download the document from the attachment.

This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender ' + - s.Email + + r.Email + ' directly. If you think this email is inappropriate or spam, you may file a complaint with OpenSign™ here.

'; if (e?.isCustomMail) try { var l, - d, c, + d, p, m, g = new Parse.Query('partners_Tenant'); - g.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: s.UserId.objectId }); - const u = await g.first(); - u && - ((l = JSON.parse(JSON.stringify(u)))?.CompletionSubject && (o = l?.CompletionSubject), + g.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: r.UserId.objectId }); + const f = await g.first(); + f && + ((l = JSON.parse(JSON.stringify(f)))?.CompletionSubject && (o = l?.CompletionSubject), l?.CompletionBody && (n = l?.CompletionBody), - (d = t.ExpiryDate.iso), - (c = new Date(d).toLocaleDateString('en-US', { + (c = a.ExpiryDate.iso), + (d = new Date(c).toLocaleDateString('en-US', { day: 'numeric', month: 'long', year: 'numeric', })), (p = { - document_title: r, - sender_name: s.Name, - sender_mail: s.Email, - sender_phone: s.Phone, - receiver_name: s.Name, - receiver_email: s.Email, - receiver_phone: s.Phone, - expiry_date: c, - company_name: s.Company, + document_title: i, + sender_name: r.Name, + sender_mail: r.Email, + sender_phone: r.Phone, + receiver_name: r.Name, + receiver_email: r.Email, + receiver_phone: r.Phone, + expiry_date: d, + company_name: r.Company, }), (m = replaceMailVaribles(o, n, p)), (o = m.subject), @@ -95,12 +106,12 @@ async function sendCompletedMail(e) { console.log('error in fetch tenant in signpdf', e.message); } g = { - extUserId: s.objectId, - url: a, + extUserId: r.objectId, + url: t, from: 'OpenSign™', - recipient: i, + recipient: s, subject: o, - pdfName: r, + pdfName: i, html: n, mailProvider: e.mailProvider, }; @@ -112,44 +123,40 @@ async function sendCompletedMail(e) { }, }); } -async function sendDoctoWebhook(t, e, a, s) { - let r = []; - (r = s - ? { name: s?.Name, email: s?.Email, phone: s?.Phone } - : t?.data?.Signers?.map(e => ({ name: e.Name, email: e.Email, phone: e.Phone })) || [ - { - name: t?.data?.ExtUserPtr?.Name, - email: t?.data?.ExtUserPtr?.Email, - phone: t?.data?.ExtUserPtr?.Phone, - }, +async function sendDoctoWebhook(a, e, t, r) { + let i = []; + (i = r + ? { name: r?.Name, email: r?.Email, phone: r?.Phone } + : a?.Signers?.map(e => ({ name: e.Name, email: e.Email, phone: e.Phone })) || [ + { name: a?.ExtUserPtr?.Name, email: a?.ExtUserPtr?.Email, phone: a?.ExtUserPtr?.Phone }, ]), - t.data.ExtUserPtr?.Webhook && - ((s = - 'signed' === a - ? { signer: r, signedAt: new Date() } - : { signers: r, completedAt: new Date() }), - (a = { - event: a, - objectId: t?.data?.objectId, + a.ExtUserPtr?.Webhook && + ((r = + 'signed' === t + ? { signer: i, signedAt: new Date() } + : { signers: i, completedAt: new Date() }), + (t = { + event: t, + objectId: a?.objectId, file: e || '', - name: t?.data?.Name, - note: t?.data?.Note || '', - description: t?.data?.Description || '', - ...s, - createdAt: t?.data?.createdAt, + name: a?.Name, + note: a?.Note || '', + description: a?.Description || '', + ...r, + createdAt: a?.createdAt, }), - await axios - .post(t?.data?.ExtUserPtr?.Webhook, a, { headers: { 'Content-Type': 'application/json' } }) + axios + .post(a?.ExtUserPtr?.Webhook, t, { headers: { 'Content-Type': 'application/json' } }) .then(e => { try { - var a = new Parse.Object('contracts_Webhook'); - a.set('Log', e?.status), - a.set('UserId', { + var t = new Parse.Object('contracts_Webhook'); + t.set('Log', e?.status), + t.set('UserId', { __type: 'Pointer', className: '_User', - objectId: t.data.ExtUserPtr.UserId.objectId, + objectId: a.ExtUserPtr.UserId.objectId, }), - a.save(null, { useMasterKey: !0 }); + t.save(null, { useMasterKey: !0 }); } catch (e) { console.log('err save in contracts_Webhook', e.message); } @@ -157,109 +164,106 @@ async function sendDoctoWebhook(t, e, a, s) { .catch(e => { console.log('Err send data to webhook', e.message); try { - var a = new Parse.Object('contracts_Webhook'); - a.set('Log', e?.status), - a.set('UserId', { + var t = new Parse.Object('contracts_Webhook'); + t.set('Log', e?.status), + t.set('UserId', { __type: 'Pointer', className: '_User', - objectId: t.data.ExtUserPtr.UserId.objectId, + objectId: a.ExtUserPtr.UserId.objectId, }), - a.save(null, { useMasterKey: !0 }); + t.save(null, { useMasterKey: !0 }); } catch (e) { console.log('err save in contracts_Webhook', e.message); } })); } +const sendMailsaveCertifcate = async (e, t, a, r, i, s) => { + var o = await GenerateCertificate(e), + o = await PDFDocument.load(o), + o = + (pdflibAddPlaceholder({ + pdfDoc: o, + reason: 'Digitally signed by OpenSign.', + location: 'n/a', + signatureLength: 15e3, + }), + await o.save()), + o = Buffer.from(o), + t = await new SignPDF(o, t).signPDF(), + t = + (fs.writeFileSync('./exports/certificate.pdf', t), + await uploadFile('certificate.pdf', './exports/certificate.pdf')), + n = { CertificateUrl: t.imageUrl }; + await axios.put(serverUrl + '/classes/contracts_Document/' + e.objectId, n, { + headers: { + 'Content-Type': 'application/json', + 'X-Parse-Application-Id': APPID, + 'X-Parse-Master-Key': masterKEY, + }, + }), + e.IsSendMail && !1 === e.IsSendMail + ? console.log("don't send mail") + : sendCompletedMail({ url: a, isCustomMail: r, doc: e, mailProvider: i }), + saveFileUsage(o.length, t.imageUrl, s), + sendDoctoWebhook(e, a, 'completed'); +}; async function PDF(o) { try { - var n = o.params.docId, - e = o.params.userId, - l = o.params.isCustomCompletionMail || !1, - d = o.params.mailProvider || '', - c = await axios.get( - serverUrl + '/classes/contracts_Document/' + n + '?include=ExtUserPtr,Signers', - { - headers: { - 'Content-Type': 'application/json', - 'X-Parse-Application-Id': APPID, - 'X-Parse-Master-Key': masterKEY, - }, - } - ), - p = await axios.get(serverUrl + '/users/me', { - headers: { - 'X-Parse-Application-Id': APPID, - 'X-Parse-Session-Token': o.headers.sessiontoken, - }, - }); - if (!p.data || !p.data.objectId) return { status: 'error', message: 'This user not allowed!' }; + if (!o?.user) + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.'); { - var a, - t, - s, - m = JSON.stringify({ objectId: e }); - let r, i; - i = e - ? (a = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + m, { - headers: { - 'X-Parse-Application-Id': APPID, - 'X-Parse-Session-Token': o.headers.sessiontoken, - }, - })).data && 0 < a.data.results.length - ? ((r = a), 'contracts_Contactbook') - : ((r = await axios.get(serverUrl + '/classes/contracts_Users?where=' + m, { - headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, - })), - 'contracts_Users') - : ((t = JSON.stringify({ - UserId: { __type: 'Pointer', className: '_User', objectId: p.data.objectId }, - })), - (s = await axios.get(serverUrl + '/classes/contracts_Users?where=' + t, { - headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, - })).data && 0 < s.data.results.length - ? ((r = s), 'contracts_Users') - : ((r = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + t, { - headers: { - 'X-Parse-Application-Id': APPID, - 'X-Parse-Session-Token': o.headers.sessiontoken, - }, - })), - 'contracts_Contactbook')); - var g = r.data.results[0].Name, - u = r.data.results[0].Email; - if (!o.params.pdfFile) return { status: 'error', message: 'Pdf file not present!' }; + var n = o?.user?.toJSON(), + e = o.params.docId; + const F = o.params.userId; + var l = o.params.isCustomCompletionMail || !1, + c = o.params.mailProvider || '', + d = o.params.signature || '', + t = new Parse.Query('contracts_Document'), + a = + (t.include('ExtUserPtr,Signers'), + t.equalTo('objectId', e), + await t.first({ useMasterKey: !0 })); + if (!a) throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Document not found.'); + var r, + p = a?.toJSON(); + let i, s; + F + ? ((r = p.Signers.find(e => e.objectId === F)), + console.log('_contractUser ', r), + r && ((i = r), (s = 'contracts_Contactbook'))) + : ((s = 'contracts_Users'), (i = p.ExtUserPtr)); + var m, + g = i.Name, + f = i.Email; + if (!o.params.pdfFile) throw (((m = new Error('Pdf file not present!')).code = 400), m); { let e = Buffer.from(o.params.pdfFile, 'base64'); - var h = process.env.PFX_BASE64, - f = Buffer.from(h, 'base64'), - P = { - UserPtr: { __type: 'Pointer', className: i, objectId: r.data.results[0].objectId }, + var u = process.env.PFX_BASE64, + h = Buffer.from(u, 'base64'), + y = { + UserPtr: { __type: 'Pointer', className: s, objectId: i.objectId }, SignedUrl: '', Activity: 'Signed', ipAddress: o.headers['x-real-ip'], }; - let a; - var y = (a = - c.data.AuditTrail && 0 < c.data.AuditTrail.length - ? [...c.data.AuditTrail, P] - : [P]).filter(e => 'Signed' === e.Activity); - let t = !1; - !( - (c.data.Signers && 0 < c.data.Signers.length && y.length !== c.data.Signers.length) || - !(t = !0) + let t; + var P = (t = p.AuditTrail && 0 < p.AuditTrail.length ? [...p.AuditTrail, y] : [y]).filter( + e => 'Signed' === e.Activity ); + let a = !1; + !((p.Signers && 0 < p.Signers.length && P.length !== p.Signers.length) || !(a = !0)); var v, b, - U, - I, + S, w, + U, D, - S = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`, - _ = './exports/' + S; - let s = e.length; - s = ( - t - ? ((v = c.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), + I = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`, + _ = './exports/' + I; + let r = e.length; + r = ( + a + ? ((v = p.Signers?.map(e => e.Name + ' <' + e.Email + '>')), (e = v && 0 < v.length ? ((b = await PDFDocument.load(e)), @@ -269,97 +273,53 @@ async function PDF(o) { location: 'n/a', signatureLength: 15e3, }), - (U = await b.save()), - Buffer.from(U)) - : ((I = await PDFDocument.load(e)), + (S = await b.save()), + Buffer.from(S)) + : ((w = await PDFDocument.load(e)), pdflibAddPlaceholder({ - pdfDoc: I, - reason: 'Digitally signed by OpenSign for ' + g + ' <' + u + '>', + pdfDoc: w, + reason: 'Digitally signed by OpenSign for ' + g + ' <' + f + '>', location: 'n/a', signatureLength: 15e3, }), - (w = await I.save()), - Buffer.from(w))), - (D = await new SignPDF(e, f).signPDF()), + (U = await w.save()), + Buffer.from(U))), + (D = await new SignPDF(e, h).signPDF()), fs.writeFileSync(_, D), D) : (fs.writeFileSync(_, e), e) ).length; - var A, - x, - E, - j, - k, - F, - C, - T, - N, - M = await uploadFile(S, _); - if (M && M.imageUrl) - return ( - (A = await updateDoc( + var E = await uploadFile(I, _); + if (E && E.imageUrl) { + var x, + A, + j = await updateDoc( o.params.docId, - M.imageUrl, - r.data.results[0].objectId, + E.imageUrl, + i.objectId, o.headers['x-real-ip'], - c.data, - i - )), - sendDoctoWebhook(c, M.imageUrl, 'signed', r?.data.results?.[0]), - saveFileUsage(s, M.imageUrl, p.data.objectId), - A && - A.isCompleted && - ((x = { ...c.data, AuditTrail: A.AuditTrail }), - (E = await GenerateCertificate(x)), - (j = await PDFDocument.load(E)), - pdflibAddPlaceholder({ - pdfDoc: j, - reason: 'Digitally signed by OpenSign.', - location: 'n/a', - signatureLength: 15e3, - }), - (k = await j.save()), - (F = Buffer.from(k)), - (C = await new SignPDF(F, f).signPDF()), - fs.writeFileSync('./exports/certificate.pdf', C), - (N = { - CertificateUrl: (T = await uploadFile( - 'certificate.pdf', - './exports/certificate.pdf' - )).imageUrl, - }), - await axios.put(serverUrl + '/classes/contracts_Document/' + n, N, { - headers: { - 'Content-Type': 'application/json', - 'X-Parse-Application-Id': APPID, - 'X-Parse-Master-Key': masterKEY, - }, - }), - c.data.IsSendMail && !1 === c.data.IsSendMail - ? console.log("don't send mail") - : sendCompletedMail({ - url: M.imageUrl, - isCustomMail: l, - doc: c.data, - mailProvider: d, - }), - saveFileUsage(F.length, T.imageUrl, p.data.objectId), - sendDoctoWebhook(c, M.imageUrl, 'completed')), + p, + s, + d + ); + if ( + (sendDoctoWebhook(p, E.imageUrl, 'signed', i), + saveFileUsage(r, E.imageUrl, n.objectId), + j && + j.isCompleted && + ((x = { ...p, AuditTrail: j.AuditTrail }), + sendMailsaveCertifcate(x, h, E.imageUrl, l, c, n.objectId)), fs.unlinkSync(_), console.log('New Signed PDF created called: ' + _), - 'success' === A.message - ? { status: 'success', data: M.imageUrl } - : { status: 'error', message: 'Please provide required parameters!' } - ); + 'success' === j.message) + ) + return { status: 'success', data: E.imageUrl }; + throw (((A = new Error('Please provide required parameters!')).code = 400), A); + } } } } catch (e) { - return ( - console.log('Err ', e), - 'ERR_BAD_REQUEST' === e.code - ? { status: 'error', message: 'Invalid session token!' } - : { status: 'error', message: 'Encrypted files are currently not supported!' } - ); + throw (console.log('Err ', e), e); } } export default PDF;