diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js index dacc083e7..8d61d3327 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js @@ -7,6 +7,8 @@ export default async function createDocumentWithTemplate(request, response) { const templateId = request.params.template_id; const protocol = customAPIurl(); const baseUrl = new URL(process.env.SERVER_URL); + const send_email = request.body.send_email || true; + try { const reqToken = request.headers['x-api-token']; if (!reqToken) { @@ -48,6 +50,8 @@ export default async function createDocumentWithTemplate(request, response) { if (template?.Description) { object.set('Description', template.Description); } + object.set('IsSendMail', send_email); + let templateSigner = template?.Signers ? template?.Signers : []; let contact = []; if (signers && signers.length > 0) { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocument.js index 0235302d7..5e92267cf 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocument.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocument.js @@ -9,6 +9,7 @@ export default async function createDocument(request, response) { const signers = request.body.signers; const folderId = request.body.folderId; const base64File = request.body.file; + const send_email = request.body.send_email || true; const fileData = request.files?.[0] ? request.files[0].buffer : null; // console.log('fileData ', fileData); const protocol = customAPIurl(); @@ -65,6 +66,7 @@ export default async function createDocument(request, response) { object.set('URL', fileUrl); object.set('CreatedBy', userPtr); object.set('ExtUserPtr', extUserPtr); + object.set('IsSendMail', send_email); if (signers && signers.length > 0) { let parseSigners; if (base64File) { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js index e651a3a92..ec67b9c20 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js @@ -1,11 +1,56 @@ import axios from 'axios'; import { color, customAPIurl } from '../../../../Utils.js'; +// `sendDoctoWebhook` is used to send res data of document on webhook +async function sendDoctoWebhook(doc, WebhookUrl, userId) { + if (WebhookUrl) { + const params = { + event: 'created', + ...doc, + }; + await axios + .post(WebhookUrl, params, { + headers: { 'Content-Type': 'application/json' }, + }) + .then(res => { + try { + // console.log('res ', res); + const webhook = new Parse.Object('contracts_Webhook'); + webhook.set('Log', res?.status); + webhook.set('UserId', { + __type: 'Pointer', + className: '_User', + objectId: userId, + }); + webhook.save(null, { useMasterKey: true }); + } catch (err) { + console.log('err save in contracts_Webhook', err); + } + }) + .catch(err => { + console.log('Err send data to webhook', err); + try { + const webhook = new Parse.Object('contracts_Webhook'); + webhook.set('Log', err?.status); + webhook.set('UserId', { + __type: 'Pointer', + className: '_User', + objectId: userId, + }); + webhook.save(null, { useMasterKey: true }); + } catch (err) { + console.log('err save in contracts_Webhook', err); + } + }); + // console.log('res ', res.data); + } +} const randomId = () => Math.floor(1000 + Math.random() * 9000); export default async function createDocumentwithCoordinate(request, response) { const name = request.body.title; const note = request.body.note; const description = request.body.description; + const send_email = request.body.send_email || true; const signers = request.body.signers; const folderId = request.body.folderId; const base64File = request.body.file; @@ -63,6 +108,7 @@ export default async function createDocumentwithCoordinate(request, response) { object.set('URL', fileUrl); object.set('CreatedBy', userPtr); object.set('ExtUserPtr', extUserPtr); + object.set('IsSendMail', send_email); let contact = []; if (signers && signers.length > 0) { let parseSigners; @@ -168,7 +214,18 @@ export default async function createDocumentwithCoordinate(request, response) { newACL.setWriteAccess(userPtr.id, true); object.setACL(newACL); const res = await object.save(null, { useMasterKey: true }); - + const doc = { + objectId: res.id, + file: fileUrl, + name: name, + note: note || '', + description: description || '', + signers: contact?.map(x => ({ name: x.name, email: x.email, phone: x.phone })), + createdAt: res.createdAt, + }; + if (parseExtUser && parseExtUser.Webhook) { + sendDoctoWebhook(doc, parseExtUser?.Webhook, userPtr?.id); + } const newDate = new Date(); newDate.setDate(newDate.getDate() + 15); const localExpireDate = newDate.toLocaleDateString('en-US', { diff --git a/apps/OpenSignServer/cloud/main.js b/apps/OpenSignServer/cloud/main.js index b02ac1894..d0838e72f 100644 --- a/apps/OpenSignServer/cloud/main.js +++ b/apps/OpenSignServer/cloud/main.js @@ -22,6 +22,7 @@ import getapitoken from './parsefunction/getapitoken.js'; import TemplateAfterSave from './parsefunction/TemplateAfterSave.js'; import GetTemplate from './parsefunction/GetTemplate.js'; import savewebhook from './parsefunction/saveWebhook.js'; +import callWebhook from './parsefunction/callWebhook.js'; Parse.Cloud.define('AddUserToRole', addUserToGroups); Parse.Cloud.define('UserGroups', getUserGroups); @@ -43,6 +44,7 @@ Parse.Cloud.define('generateapitoken', generateApiToken); Parse.Cloud.define('getapitoken', getapitoken); Parse.Cloud.define('getTemplate', GetTemplate); Parse.Cloud.define('savewebhook', savewebhook); +Parse.Cloud.define('callwebhook', callWebhook); Parse.Cloud.afterSave('contracts_Document', DocumentAftersave); Parse.Cloud.afterSave('contracts_Contactbook', ContactbookAftersave); Parse.Cloud.afterSave('contracts_Users', ContractUsersAftersave); diff --git a/apps/OpenSignServer/cloud/parsefunction/callWebhook.js b/apps/OpenSignServer/cloud/parsefunction/callWebhook.js new file mode 100644 index 000000000..7e2fa4056 --- /dev/null +++ b/apps/OpenSignServer/cloud/parsefunction/callWebhook.js @@ -0,0 +1,66 @@ +import axios from 'axios'; +export default async function callWebhook(request) { + const event = request.params.event; + const body = request.params.body; + const serverUrl = process.env.SERVER_URL; + const appId = process.env.APP_ID; + const userRes = await axios.get(serverUrl + '/users/me', { + headers: { + 'X-Parse-Application-Id': appId, + 'X-Parse-Session-Token': request.headers['sessiontoken'], + }, + }); + + const userId = userRes.data && userRes.data.objectId; + if (userId) { + const extendcls = new Parse.Query('contracts_Users'); + extendcls.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: userId }); + const res = await extendcls.first({ useMasterKey: true }); + if (res) { + const extUser = JSON.parse(JSON.stringify(res)); + if (extUser?.Webhook) { + const params = { + event: event, + ...body, + }; + await axios + .post(extUser?.Webhook, params, { + headers: { 'Content-Type': 'application/json' }, + }) + .then(res => { + try { + // console.log('res ', res); + const webhook = new Parse.Object('contracts_Webhook'); + webhook.set('Log', res?.status); + webhook.set('UserId', { + __type: 'Pointer', + className: '_User', + objectId: userId, + }); + webhook.save(null, { useMasterKey: true }); + } catch (err) { + console.log('err save in contracts_Webhook', err); + } + }) + .catch(err => { + console.log('Err send data to webhook', err); + try { + const webhook = new Parse.Object('contracts_Webhook'); + webhook.set('Log', err?.status); + webhook.set('UserId', { + __type: 'Pointer', + className: '_User', + objectId: userId, + }); + webhook.save(null, { useMasterKey: true }); + } catch (err) { + console.log('err save in contracts_Webhook', err); + } + }); + } + return { message: 'webhook called!' }; + } + } else { + return { message: 'User not found!' }; + } +} diff --git a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js index a70ea21c0..8ff68542b 100644 --- a/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js +++ b/apps/OpenSignServer/cloud/parsefunction/pdf/PDF.min.js @@ -15,20 +15,20 @@ async function uploadFile(e, a) { console.log('Err ', e), fs.unlinkSync(a); } } -async function updateDoc(t, s, r, i, o, n) { +async function updateDoc(t, s, r, i, n, o) { try { var d = { - UserPtr: { __type: 'Pointer', className: n, objectId: r }, + UserPtr: { __type: 'Pointer', className: o, objectId: r }, SignedUrl: s, Activity: 'Signed', ipAddress: i, }; let e; - var l = (e = o.AuditTrail && 0 < o.AuditTrail.length ? [...o.AuditTrail, d] : [d]).filter( + var l = (e = n.AuditTrail && 0 < n.AuditTrail.length ? [...n.AuditTrail, d] : [d]).filter( e => 'Signed' === e.Activity ); let a = !1; - !((o.Signers && 0 < o.Signers.length && l.length !== o.Signers.length) || !(a = !0)); + !((n.Signers && 0 < n.Signers.length && l.length !== n.Signers.length) || !(a = !0)); var c = { SignedUrl: s, AuditTrail: e, IsCompleted: a }; await axios.put(serverUrl + '/classes/contracts_Document/' + t, c, { headers: { @@ -95,27 +95,28 @@ 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: 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, + 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() }), + 'signed' === a + ? { signer: r, signedAt: new Date() } + : { signers: r, completedAt: new Date() }), (a = { - Event: a, - File: e || '', - Name: t?.data?.Name, - Note: t?.data?.Note || '', - Description: t?.data?.Description || '', + 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, + createdAt: t?.data?.createdAt, }), await axios .post(t?.data?.ExtUserPtr?.Webhook, a, { headers: { 'Content-Type': 'application/json' } }) @@ -149,12 +150,12 @@ async function sendDoctoWebhook(t, e, a, s) { } })); } -async function PDF(i, o) { +async function PDF(i, n) { try { i.params.sign; var e = i.params.docId, a = i.params.userId, - n = await axios.get( + o = await axios.get( serverUrl + '/classes/contracts_Document/' + e + '?include=ExtUserPtr,Signers', { headers: { @@ -218,26 +219,26 @@ async function PDF(i, o) { }; let a; var y = (a = - n.data.AuditTrail && 0 < n.data.AuditTrail.length - ? [...n.data.AuditTrail, f] + o.data.AuditTrail && 0 < o.data.AuditTrail.length + ? [...o.data.AuditTrail, f] : [f]).filter(e => 'Signed' === e.Activity); let t = !1; !( - (n.data.Signers && 0 < n.data.Signers.length && y.length !== n.data.Signers.length) || + (o.data.Signers && 0 < o.data.Signers.length && y.length !== o.data.Signers.length) || !(t = !0) ); - var P, - v, + var v, + P, b = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`, x = './exports/' + b, U = (t - ? ((P = n.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), + ? ((v = o.data.Signers?.map(e => e.Name + ' <' + e.Email + '>')), (e = - P && 0 < P.length + v && 0 < v.length ? plainAddPlaceholder({ pdfBuffer: e, - reason: 'Digitally signed by Open sign for ' + P?.join(', '), + reason: 'Digitally signed by Open sign for ' + v?.join(', '), location: 'location', signatureLength: 1e4, }) @@ -247,39 +248,42 @@ async function PDF(i, o) { location: 'location', signatureLength: 1e4, })), - (v = await new SignPDF(e, u).signPDF()), - fs.writeFileSync(x, v)) + (P = await new SignPDF(e, u).signPDF()), + fs.writeFileSync(x, P)) : fs.writeFileSync(x, e), await uploadFile(b, x)); if (U && U.imageUrl) { - const o = await updateDoc( + const n = await updateDoc( i.params.docId, U.imageUrl, s.data.results[0].objectId, i.headers['x-real-ip'], - n.data, + o.data, r ); - return ( - sendMail({ + var I, + w = { url: U.imageUrl, - sender: { Mail: n.data.ExtUserPtr.Email, Name: n.data.ExtUserPtr.Name }, - pdfName: n.data.Name, + sender: { Mail: o.data.ExtUserPtr.Email, Name: o.data.ExtUserPtr.Name }, + pdfName: o.data.Name, receiver: g, - }), - sendDoctoWebhook(n, U.imageUrl, 'Signed', s?.data.results?.[0]), - o && - o.isCompleted && - (sendCompletedMail({ + }; + return ( + o.data.IsSendMail && sendMail(w), + sendDoctoWebhook(o, U.imageUrl, 'signed', s?.data.results?.[0]), + n && + n.isCompleted && + ((I = { url: U.imageUrl, - sender: { Mail: n.data.ExtUserPtr.Email, Name: 'OpenSign™' }, - pdfName: n.data.Name, - receiver: n.data.ExtUserPtr.Email, + sender: { Mail: o.data.ExtUserPtr.Email, Name: 'OpenSign™' }, + pdfName: o.data.Name, + receiver: o.data.ExtUserPtr.Email, }), - sendDoctoWebhook(n, U.imageUrl, 'Completed')), + o.data.IsSendMail && sendCompletedMail(I), + sendDoctoWebhook(o, U.imageUrl, 'completed')), fs.unlinkSync(x), console.log('New Signed PDF created called: ' + x), - 'success' === o.message + 'success' === n.message ? { status: 'success', data: U.imageUrl } : { status: 'error', message: 'please provide required parameters!' } ); diff --git a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js index 901c37a3f..924c7c5c1 100644 --- a/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js +++ b/microfrontends/SignDocuments/src/Component/PdfRequestFiles.js @@ -609,9 +609,37 @@ function PdfRequestFiles() { } } ) - .then((result) => { + .then(async (result) => { const res = result.data; if (res) { + const params = { + event: "declined", + body: { + objectId: pdfDetails?.[0].objectId, + name: pdfDetails?.[0].Name, + note: pdfDetails?.[0].Note || "", + description: pdfDetails?.[0].Description || "", + signers: pdfDetails?.[0].Signers?.map((x) => ({ + name: x?.Name, + email: x?.Email, + phone: x?.Phone + })), + createdAt: pdfDetails?.[0].createdAt, + declinedAt: new Date() + } + }; + const res = await axios.post( + `${localStorage.getItem("baseUrl")}functions/callwebhook`, + params, + { + headers: { + "Content-Type": "application/json", + "X-Parse-Application-Id": localStorage.getItem("parseAppId"), + sessiontoken: localStorage.getItem("accesstoken") + } + } + ); + console.log("res ", res.data); const currentDecline = { currnt: "YouDeclined", isDeclined: true