import fs from 'node:fs'; import axios from 'axios'; import { SignPdf } from '@signpdf/signpdf'; import { P12Signer } from '@signpdf/signer-p12'; import { pdflibAddPlaceholder } from '@signpdf/placeholder-pdf-lib'; 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, eSignName = 'opensign', eSigncontact = 'hello@opensignlabs.com'; async function uploadFile(e, t) { try { 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(t); } } async function updateDoc(a, r, i, n, s, o, l) { try { var c, d, p = { UserPtr: { __type: 'Pointer', className: o, objectId: i }, SignedUrl: r, Activity: 'Signed', ipAddress: n, SignedOn: new Date(), Signature: l, }; let e; var m = (e = s.AuditTrail && 0 < s.AuditTrail.length ? (-1 !== (d = (c = JSON.parse(JSON.stringify(s.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; !((s.Signers && 0 < s.Signers.length && m.length !== s.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: t, message: 'success', AuditTrail: e }; } catch (e) { return console.log('update doc err ', e), 'err'; } } async function sendCompletedMail(e) { var t = e.url, a = e.doc, r = e.doc.ExtUserPtr, i = a.Name, n = r.Email; let s = `Document "${i}" has been signed by all parties`, o = "

Document signed successfully

All parties have successfully signed the document " + `"${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 ' + 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, c, d, p, m, g = new Parse.Query('partners_Tenant'); g.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: r.UserId.objectId }); const f = await g.first(); f && ((l = JSON.parse(JSON.stringify(f)))?.CompletionSubject && (s = l?.CompletionSubject), l?.CompletionBody && (o = l?.CompletionBody), (c = a.ExpiryDate.iso), (d = new Date(c).toLocaleDateString('en-US', { day: 'numeric', month: 'long', year: 'numeric', })), (p = { 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(s, o, p)), (s = m.subject), (o = m.body)); } catch (e) { console.log('error in fetch tenant in signpdf', e.message); } g = { extUserId: r.objectId, url: t, from: 'OpenSign™', recipient: n, subject: s, pdfName: i, html: o, mailProvider: e.mailProvider, }; await axios.post(serverUrl + '/functions/sendmailv3', g, { headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APPID, 'X-Parse-Master-Key': masterKEY, }, }); } async function sendDoctoWebhook(a, e, t, r, i) { let n = []; (n = 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 }, ]), a.ExtUserPtr?.Webhook && ((r = 'signed' === t ? { signer: n, signedAt: new Date() } : { signers: n, completedAt: new Date() }), (t = { event: t, objectId: a?.objectId, file: e || '', ...(i ? { certificate: i } : {}), name: a?.Name, note: a?.Note || '', description: a?.Description || '', ...r, createdAt: a?.createdAt, }), axios .post(a?.ExtUserPtr?.Webhook, t, { headers: { 'Content-Type': 'application/json' } }) .then(e => { try { var t = new Parse.Object('contracts_Webhook'); t.set('Log', e?.status), t.set('UserId', { __type: 'Pointer', className: '_User', objectId: a.ExtUserPtr.UserId.objectId, }), t.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 t = new Parse.Object('contracts_Webhook'); t.set('Log', e?.status), t.set('UserId', { __type: 'Pointer', className: '_User', objectId: a.ExtUserPtr.UserId.objectId, }), t.save(null, { useMasterKey: !0 }); } catch (e) { console.log('err save in contracts_Webhook', e.message); } })); } const sendMailsaveCertifcate = async (e, t, a, r, i, n) => { var s = await GenerateCertificate(e), s = await PDFDocument.load(s), t = new P12Signer(t, { passphrase: process.env.PASS_PHRASE || null }), s = (pdflibAddPlaceholder({ pdfDoc: s, reason: 'Digitally signed by OpenSign.', location: 'n/a', name: eSignName, contactInfo: eSigncontact, signatureLength: 15e3, }), await s.save()), s = Buffer.from(s), t = await new SignPdf().sign(s, t), t = (fs.writeFileSync('./exports/certificate.pdf', t), await uploadFile('certificate.pdf', './exports/certificate.pdf')), o = { CertificateUrl: t.imageUrl }; await axios.put(serverUrl + '/classes/contracts_Document/' + e.objectId, o, { 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(s.length, t.imageUrl, n), sendDoctoWebhook(e, a, 'completed', '', t.imageUrl); }; async function PDF(s) { try { if (!s?.user) throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.'); { var o = s?.user?.toJSON(), e = s.params.docId; const C = s.params.userId; var l = s.params.isCustomCompletionMail || !1, c = s.params.mailProvider || '', d = s.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, n; C ? ((r = p.Signers.find(e => e.objectId === C)), console.log('_contractUser ', r), r && ((i = r), (n = 'contracts_Contactbook'))) : ((n = 'contracts_Users'), (i = p.ExtUserPtr)); var m, g = i.Name, f = i.Email; if (!s.params.pdfFile) throw (((m = new Error('Pdf file not present!')).code = 400), m); { let e = Buffer.from(s.params.pdfFile, 'base64'); var u = process.env.PFX_BASE64, h = Buffer.from(u, 'base64'), y = new P12Signer(h, { passphrase: process.env.PASS_PHRASE || null }), P = { UserPtr: { __type: 'Pointer', className: n, objectId: i.objectId }, SignedUrl: '', Activity: 'Signed', ipAddress: s.headers['x-real-ip'], }; let t; var v = (t = p.AuditTrail && 0 < p.AuditTrail.length ? [...p.AuditTrail, P] : [P]).filter( e => 'Signed' === e.Activity ); let a = !1; !((p.Signers && 0 < p.Signers.length && v.length !== p.Signers.length) || !(a = !0)); var S, b, w, U, I, _, E = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`, D = './exports/' + E; let r = e.length; r = ( a ? ((S = p.Signers?.map(e => e.Name + ' <' + e.Email + '>')), (e = S && 0 < S.length ? ((b = await PDFDocument.load(e)), pdflibAddPlaceholder({ pdfDoc: b, reason: 'Digitally signed by OpenSign for ' + S?.join(', '), location: 'n/a', name: eSignName, contactInfo: eSigncontact, signatureLength: 15e3, }), (w = await b.save()), Buffer.from(w)) : ((U = await PDFDocument.load(e)), pdflibAddPlaceholder({ pdfDoc: U, reason: 'Digitally signed by OpenSign for ' + g + ' <' + f + '>', location: 'n/a', name: eSignName, contactInfo: eSigncontact, signatureLength: 15e3, }), (I = await U.save()), Buffer.from(I))), (_ = await new SignPdf().sign(e, y)), fs.writeFileSync(D, _), _) : (fs.writeFileSync(D, e), e) ).length; var A = await uploadFile(E, D); if (A && A.imageUrl) { var x, j, N = await updateDoc( s.params.docId, A.imageUrl, i.objectId, s.headers['x-real-ip'], p, n, d ); if ( (sendDoctoWebhook(p, A.imageUrl, 'signed', i), saveFileUsage(r, A.imageUrl, o.objectId), N && N.isCompleted && ((x = { ...p, AuditTrail: N.AuditTrail }), sendMailsaveCertifcate(x, h, A.imageUrl, l, c, o.objectId)), fs.unlinkSync(D), console.log('New Signed PDF created called: ' + D), 'success' === N.message) ) return { status: 'success', data: A.imageUrl }; throw (((j = new Error('Please provide required parameters!')).code = 400), j); } } } } catch (e) { throw (console.log('Err in signpdf', e), e); } } export default PDF;