import SignPDF from './SignPDF.min.cjs'; import fs from 'node:fs'; import axios from 'axios'; import { pdflibAddPlaceholder } from './customSignPdf/pdflibplaceholder.min.js'; import { PDFDocument } from 'pdf-lib'; import { replaceMailVaribles, saveFileUsage } from '../../../Utils.js'; 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) { 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 }; } catch (e) { console.log('Err ', e), fs.unlinkSync(a); } } async function updateDoc(t, s, r, i, o, n) { try { var l = { UserPtr: { __type: 'Pointer', className: n, objectId: r }, SignedUrl: s, Activity: 'Signed', ipAddress: i, }; 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, { headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY, }, }); return { isCompleted: a, 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`, n = "

Document signed successfully

All parties have successfully signed the document " + `"${r}"` + '. 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 + ' 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, 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), l?.CompletionBody && (n = l?.CompletionBody), (d = t.ExpiryDate.iso), (c = new Date(d).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, }), (m = replaceMailVaribles(o, n, p)), (o = m.subject), (n = m.body)); } catch (e) { console.log('error in fetch tenant in signpdf', e.message); } e = { extUserId: s.objectId, url: a, from: 'OpenSign™', recipient: i, subject: o, pdfName: r, html: n, }; await axios.post(serverUrl + '/functions/sendmailv3', e, { headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY, }, }); } 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, }, ]), t.data.ExtUserPtr?.Webhook && ((s = 'signed' === a ? { signer: r, signedAt: new Date() } : { signers: r, completedAt: new Date() }), (a = { event: a, objectId: t?.data?.objectId, file: e || '', name: t?.data?.Name, note: t?.data?.Note || '', description: t?.data?.Description || '', ...s, createdAt: t?.data?.createdAt, }), await axios .post(t?.data?.ExtUserPtr?.Webhook, a, { headers: { 'Content-Type': 'application/json' } }) .then(e => { try { var a = new Parse.Object('contracts_Webhook'); a.set('Log', e?.status), a.set('UserId', { __type: 'Pointer', className: '_User', objectId: t.data.ExtUserPtr.UserId.objectId, }), a.save(null, { useMasterKey: !0 }); } catch (e) { console.log('err save in contracts_Webhook', e.message); } }) .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', { __type: 'Pointer', className: '_User', objectId: t.data.ExtUserPtr.UserId.objectId, }), a.save(null, { useMasterKey: !0 }); } catch (e) { console.log('err save in contracts_Webhook', e.message); } })); } async function PDF(o) { try { var n = o.params.docId, e = o.params.userId, l = o.params.isCustomCompletionMail, d = 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, }, } ), c = await axios.get(serverUrl + '/users/me', { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Session-Token': o.headers.sessiontoken, }, }); if (!c.data || !c.data.objectId) return { status: 'error', message: 'This user not allowed!' }; { var a, t, s, p = JSON.stringify({ objectId: e }); let r, i; i = e ? (a = await axios.get(serverUrl + '/classes/contracts_Contactbook?where=' + p, { 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=' + p, { headers: { 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY }, })), 'contracts_Users') : ((t = JSON.stringify({ UserId: { __type: 'Pointer', className: '_User', objectId: c.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 m = r.data.results[0].Name, g = r.data.results[0].Email; if (!o.params.pdfFile) return { status: 'error', message: 'Pdf file not present!' }; { let e = Buffer.from(o.params.pdfFile, 'base64'); var u = process.env.PFX_BASE64, h = Buffer.from(u, 'base64'), f = { UserPtr: { __type: 'Pointer', className: i, objectId: r.data.results[0].objectId }, SignedUrl: '', Activity: 'Signed', ipAddress: o.headers['x-real-ip'], }; let a; var P = (a = d.data.AuditTrail && 0 < d.data.AuditTrail.length ? [...d.data.AuditTrail, f] : [f]).filter(e => 'Signed' === e.Activity); let t = !1; !( (d.data.Signers && 0 < d.data.Signers.length && P.length !== d.data.Signers.length) || !(t = !0) ); var y, b, v, U, I, w, D = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`, S = './exports/' + D; let s = e.length; s = ( t ? ((y = d.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), (e = y && 0 < y.length ? ((b = await PDFDocument.load(e)), pdflibAddPlaceholder({ pdfDoc: b, reason: 'Digitally signed by OpenSign for ' + y?.join(', '), location: 'n/a', signatureLength: 15e3, }), (v = await b.save()), Buffer.from(v)) : ((U = await PDFDocument.load(e)), pdflibAddPlaceholder({ pdfDoc: U, reason: 'Digitally signed by OpenSign for ' + m + ' <' + g + '>', location: 'n/a', signatureLength: 15e3, }), (I = await U.save()), Buffer.from(I))), (w = await new SignPDF(e, h).signPDF()), fs.writeFileSync(S, w), w) : (fs.writeFileSync(S, e), e) ).length; var _, A, x, E, j, k, F, C, T, N = await uploadFile(D, S); if (N && N.imageUrl) return ( (_ = await updateDoc( o.params.docId, N.imageUrl, r.data.results[0].objectId, o.headers['x-real-ip'], d.data, i )), sendDoctoWebhook(d, N.imageUrl, 'signed', r?.data.results?.[0]), saveFileUsage(s, N.imageUrl, c.data.objectId), _ && _.isCompleted && ((A = { ...d.data, AuditTrail: _.AuditTrail }), (x = await GenerateCertificate(A)), (E = await PDFDocument.load(x)), pdflibAddPlaceholder({ pdfDoc: E, reason: 'Digitally signed by OpenSign.', location: 'n/a', signatureLength: 15e3, }), (j = await E.save()), (k = Buffer.from(j)), (F = await new SignPDF(k, h).signPDF()), fs.writeFileSync('./exports/certificate.pdf', F), (T = { CertificateUrl: (C = await uploadFile( 'certificate.pdf', './exports/certificate.pdf' )).imageUrl, }), await axios.put(serverUrl + '/classes/contracts_Document/' + n, T, { headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY, }, }), d.data.IsSendMail && !1 === d.data.IsSendMail ? console.log("don't send mail") : sendCompletedMail({ url: N.imageUrl, isCustomMail: l, doc: d.data }), saveFileUsage(k.length, C.imageUrl, c.data.objectId), sendDoctoWebhook(d, N.imageUrl, 'completed')), fs.unlinkSync(S), console.log('New Signed PDF created called: ' + S), 'success' === _.message ? { status: 'success', data: N.imageUrl } : { status: 'error', message: 'Please provide required parameters!' } ); } } } 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!' } ); } } export default PDF;