diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js index 08a066e86..4b108ac87 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js @@ -61,11 +61,16 @@ export default async function createDocumentWithTemplate(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); - + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; const templateQuery = new Parse.Query('contracts_Template'); templateQuery.include('ExtUserPtr'); const templateRes = await templateQuery.get(templateId, { useMasterKey: true }); @@ -170,8 +175,8 @@ export default async function createDocumentWithTemplate(request, response) { const newACL = new Parse.ACL(); newACL.setPublicReadAccess(false); newACL.setPublicWriteAccess(false); - newACL.setReadAccess(userPtr.id, true); - newACL.setWriteAccess(userPtr.id, true); + newACL.setReadAccess(userPtr.objectId, true); + newACL.setWriteAccess(userPtr.objectId, true); object.setACL(newACL); const res = await object.save(null, { useMasterKey: true }); @@ -287,11 +292,18 @@ export default async function createDocumentWithTemplate(request, response) { createdAt: res.createdAt, }; if (template.ExtUserPtr && template.ExtUserPtr?.Webhook) { - sendDoctoWebhook(doc, template.ExtUserPtr?.Webhook, userPtr?.id); + sendDoctoWebhook(doc, template.ExtUserPtr?.Webhook, userPtr?.objectId); } } catch (err) { console.log('Err', err); } + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_document_with_templateid', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: res.id, signurl: contact.map(x => ({ @@ -302,12 +314,33 @@ export default async function createDocumentWithTemplate(request, response) { }); // } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_document_with_templateid', + properties: { response_code: 400 }, + }); + } return response.status(400).json({ error: 'Please provide signers properly!' }); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_document_with_templateid', + properties: { response_code: 400 }, + }); + } return response.status(400).json({ error: 'Please setup template properly!' }); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_document_with_templateid', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Invalid template id!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createContact.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createContact.js index 879217e92..b0160a4aa 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createContact.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createContact.js @@ -11,10 +11,17 @@ export default async function createContact(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; + try { const contactbook = new Parse.Query('contracts_Contactbook'); contactbook.equalTo('Email', email); @@ -23,6 +30,13 @@ export default async function createContact(request, response) { const userExists = await contactbook.first({ useMasterKey: true }); if (userExists) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_contact', + properties: { response_code: 401 }, + }); + } return response .status(401) .json({ error: 'Contact already exists!', objectId: userExists.id }); @@ -72,8 +86,8 @@ export default async function createContact(request, response) { contactQuery.set('UserId', user); const acl = new Parse.ACL(); - acl.setReadAccess(userPtr.id, true); - acl.setWriteAccess(userPtr.id, true); + acl.setReadAccess(userPtr.objectId, true); + acl.setWriteAccess(userPtr.objectId, true); acl.setReadAccess(user.id, true); acl.setWriteAccess(user.id, true); contactQuery.setACL(acl); @@ -103,18 +117,18 @@ export default async function createContact(request, response) { const body = { appName: 'contracts', roleName: 'contracts_Guest', - userId: userRes.id, + userId: userRes.objectId, }; await axios.post(roleurl, body, { headers: headers }); - contactQuery.set('CreatedBy', userPtr); + contactQuery.set('CreatedBy', userPtr.objectId); contactQuery.set('UserId', { __type: 'Pointer', className: '_User', objectId: userRes.id, }); const acl = new Parse.ACL(); - acl.setReadAccess(userPtr.id, true); - acl.setWriteAccess(userPtr.id, true); + acl.setReadAccess(userPtr.objectId, true); + acl.setWriteAccess(userPtr.objectId, true); acl.setReadAccess(userRes.id, true); acl.setWriteAccess(userRes.id, true); @@ -143,8 +157,22 @@ export default async function createContact(request, response) { } catch (err) { console.log('err ', err); if (err.code === 137) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_contact', + properties: { response_code: 401 }, + }); + } return response.status(401).json({ error: 'Contact already exists!' }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_contact', + properties: { response_code: 400 }, + }); + } return response .status(400) .json({ error: 'Something went wrong, please try again later!' }); @@ -152,6 +180,13 @@ export default async function createContact(request, response) { } } } catch (err) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_contact', + properties: { response_code: 400 }, + }); + } return response.status(400).json({ error: 'Something went wrong, please try again later!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocument.js index 1b88369a2..33f89b21a 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocument.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocument.js @@ -21,11 +21,17 @@ export default async function createDocument(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; // Valid Token then proceed request if (signers && signers.length > 0) { - const userPtr = token.get('userId'); let fileUrl; if (request.files?.[0]) { const file = new Parse.File(request.files?.[0]?.originalname, { @@ -112,15 +118,29 @@ export default async function createDocument(request, response) { const newACL = new Parse.ACL(); newACL.setPublicReadAccess(false); newACL.setPublicWriteAccess(false); - newACL.setReadAccess(userPtr.id, true); - newACL.setWriteAccess(userPtr.id, true); + newACL.setReadAccess(userPtr.objectId, true); + newACL.setWriteAccess(userPtr.objectId, true); object.setACL(newACL); const res = await object.save(null, { useMasterKey: true }); + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'draft_document', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: res.id, url: protocol + '/load/signmicroapp/placeholdersign/' + res.id, }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'draft_document', + properties: { response_code: 400 }, + }); + } return response.status(400).json({ error: 'Please provide signers!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js index cd285a905..3f5b30171 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js @@ -67,11 +67,17 @@ export default async function createDocumentwithCoordinate(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; if (signers && signers.length > 0) { - const userPtr = token.get('userId'); let fileUrl; if (request.files?.[0]) { const file = new Parse.File(request.files?.[0]?.originalname, { @@ -211,8 +217,8 @@ export default async function createDocumentwithCoordinate(request, response) { const newACL = new Parse.ACL(); newACL.setPublicReadAccess(false); newACL.setPublicWriteAccess(false); - newACL.setReadAccess(userPtr.id, true); - newACL.setWriteAccess(userPtr.id, true); + newACL.setReadAccess(userPtr.objectId, true); + newACL.setWriteAccess(userPtr.objectId, true); object.setACL(newACL); const res = await object.save(null, { useMasterKey: true }); const doc = { @@ -225,7 +231,7 @@ export default async function createDocumentwithCoordinate(request, response) { createdAt: res.createdAt, }; if (parseExtUser && parseExtUser.Webhook) { - sendDoctoWebhook(doc, parseExtUser?.Webhook, userPtr?.id); + sendDoctoWebhook(doc, parseExtUser?.Webhook, userPtr?.objectId); } const newDate = new Date(); newDate.setDate(newDate.getDate() + 15); @@ -328,6 +334,13 @@ export default async function createDocumentwithCoordinate(request, response) { } } // if (sendMail.data.result.status === 'success') { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_document', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: res.id, signurl: contact.map(x => ({ @@ -338,6 +351,13 @@ export default async function createDocumentwithCoordinate(request, response) { }); // } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_document', + properties: { response_code: 400 }, + }); + } return response.status(400).json({ error: 'Please provide signers!' }); } } else { @@ -345,6 +365,6 @@ export default async function createDocumentwithCoordinate(request, response) { } } catch (err) { console.log('err ', err); - return response.status(400).json({ error: 'Something went wrong!' }); + return response.status(400).json({ error: 'Something went wrong, please try again later!' }); } } diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplate.js index 5d8e4fb14..742f487ba 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplate.js @@ -18,10 +18,16 @@ export default async function createTemplate(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; let fileUrl; if (base64File) { const file = new Parse.File(`${name}.pdf`, { @@ -100,10 +106,17 @@ export default async function createTemplate(request, response) { const newACL = new Parse.ACL(); newACL.setPublicReadAccess(false); newACL.setPublicWriteAccess(false); - newACL.setReadAccess(userPtr.id, true); - newACL.setWriteAccess(userPtr.id, true); + newACL.setReadAccess(userPtr.objectId, true); + newACL.setWriteAccess(userPtr.objectId, true); object.setACL(newACL); const res = await object.save(null, { useMasterKey: true }); + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'draft_template', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: res.id, url: protocol + '/load/signmicroapp/template/' + res.id, diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplatewithCoordinate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplatewithCoordinate.js index 528827561..fd0a045db 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplatewithCoordinate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createTemplatewithCoordinate.js @@ -20,11 +20,17 @@ export default async function createTemplatewithCoordinate(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; if (signers && signers.length > 0) { - const userPtr = token.get('userId'); let fileUrl; if (request.files?.[0]) { const file = new Parse.File(request.files?.[0]?.originalname, { @@ -169,16 +175,29 @@ export default async function createTemplatewithCoordinate(request, response) { const newACL = new Parse.ACL(); newACL.setPublicReadAccess(false); newACL.setPublicWriteAccess(false); - newACL.setReadAccess(userPtr.id, true); - newACL.setWriteAccess(userPtr.id, true); + newACL.setReadAccess(userPtr.objectId, true); + newACL.setWriteAccess(userPtr.objectId, true); object.setACL(newACL); const res = await object.save(null, { useMasterKey: true }); - + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_template', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: res.id, message: 'Template created successfully!', }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'create_template', + properties: { response_code: 400 }, + }); + } return response.status(400).json({ error: 'Please provide signers!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteContact.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteContact.js index b9e57012a..ade460c9c 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteContact.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteContact.js @@ -6,10 +6,17 @@ export default async function deleteContact(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; + const Contactbook = new Parse.Query('contracts_Contactbook'); Contactbook.equalTo('objectId', request.params.contact_id); Contactbook.equalTo('CreatedBy', userPtr); @@ -25,6 +32,13 @@ export default async function deleteContact(request, response) { deleteQuery.set('IsDeleted', true); const deleteRes = await deleteQuery.save(null, { useMasterKey: true }); if (deleteRes) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'delete_contact', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: request.params.contact_id, deletedAt: deleteRes.get('updatedAt'), @@ -32,6 +46,13 @@ export default async function deleteContact(request, response) { } } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'delete_contact', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Contact not found!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteDocument.js index 543dd73ba..1094fe887 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteDocument.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteDocument.js @@ -6,10 +6,17 @@ export default async function deleteDocument(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; + const Document = new Parse.Query('contracts_Document'); Document.equalTo('objectId', request.params.document_id); Document.equalTo('CreatedBy', userPtr); @@ -25,6 +32,13 @@ export default async function deleteDocument(request, response) { deleteQuery.set('IsArchive', true); const deleteRes = await deleteQuery.save(null, { useMasterKey: true }); if (deleteRes) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'delete_document', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: request.params.document_id, deletedAt: deleteRes.get('updatedAt'), @@ -32,6 +46,13 @@ export default async function deleteDocument(request, response) { } } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'delete_document', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Document not found!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteTemplate.js index 9967f9001..d22417e9c 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteTemplate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteTemplate.js @@ -6,10 +6,16 @@ export default async function deletedTemplate(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; const template = new Parse.Query('contracts_Template'); template.equalTo('objectId', request.params.template_id); template.equalTo('CreatedBy', userPtr); @@ -25,6 +31,13 @@ export default async function deletedTemplate(request, response) { deleteQuery.set('IsArchive', true); const deleteRes = await deleteQuery.save(null, { useMasterKey: true }); if (deleteRes) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'delete_template', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: request.params.template_id, deletedAt: deleteRes.get('updatedAt'), @@ -32,6 +45,13 @@ export default async function deletedTemplate(request, response) { } } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'delete_template', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Template not found!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteWebhook.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteWebhook.js index b51be025a..23cdf6cde 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteWebhook.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/deleteWebhook.js @@ -5,10 +5,17 @@ export default async function deleteWebhook(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; + const query = new Parse.Query('contracts_Users'); query.equalTo('UserId', userPtr); const user = await query.first({ useMasterKey: true }); @@ -18,11 +25,25 @@ export default async function deleteWebhook(request, response) { updateQuery.unset('Webhook'); const res = await updateQuery.save(null, { useMasterKey: true }); if (res) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'delete_webhook', + properties: { response_code: 200 }, + }); + } return response.json({ result: 'Webhook deleted successfully!', }); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'delete_webhook', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'User not found!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getContact.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getContact.js index e400cd372..15270b088 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/getContact.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getContact.js @@ -6,10 +6,17 @@ export default async function getContact(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; + const Contactbook = new Parse.Query('contracts_Contactbook'); Contactbook.equalTo('objectId', request.params.contact_id); Contactbook.equalTo('CreatedBy', userPtr); @@ -19,6 +26,13 @@ export default async function getContact(request, response) { const res = await Contactbook.first({ useMasterKey: true }); if (res) { const parseRes = JSON.parse(JSON.stringify(res)); + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_contact', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: parseRes.objectId, name: parseRes.Name, @@ -28,6 +42,13 @@ export default async function getContact(request, response) { updatedAt: parseRes.updatedAt, }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_contact', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Contact not found!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getContactList.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getContactList.js index 3ecfc7885..b0d473d4b 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/getContactList.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getContactList.js @@ -6,10 +6,16 @@ export default async function getContactList(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; const limit = request?.query?.limit ? parseInt(request.query.limit) : 100; const skip = request?.query?.skip ? parseInt(request.query.skip) : 0; const Contactbook = new Parse.Query('contracts_Contactbook'); @@ -29,8 +35,22 @@ export default async function getContactList(request, response) { createdAt: x.createdAt, updatedAt: x.updatedAt, })); + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_contact_list', + properties: { response_code: 200 }, + }); + } return response.json({ result: contactlist }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_contact_list', + properties: { response_code: 200 }, + }); + } return response.json({ result: [] }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocument.js index 4643460ae..4ba439673 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocument.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocument.js @@ -6,10 +6,16 @@ export default async function getDocument(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; const Document = new Parse.Query('contracts_Document'); Document.equalTo('objectId', request.params.document_id); Document.equalTo('CreatedBy', userPtr); @@ -20,6 +26,13 @@ export default async function getDocument(request, response) { const res = await Document.first({ useMasterKey: true }); if (res) { const document = JSON.parse(JSON.stringify(res)); + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_document', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: document.objectId, title: document.Name, @@ -34,6 +47,13 @@ export default async function getDocument(request, response) { updatedAt: document.updatedAt, }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_document', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Document not found!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocumentList.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocumentList.js index a4cf04d12..4540a5ec2 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocumentList.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getDocumentList.js @@ -12,10 +12,16 @@ export default async function getDocumentList(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; const docType = request.params.doctype; const limit = request?.query?.limit ? request.query.limit : 100; const skip = request?.query?.skip ? request.query.skip : 0; @@ -42,7 +48,7 @@ export default async function getDocumentList(request, response) { default: reportId = ''; } - const json = reportId && reportJson(reportId, userPtr.id); + const json = reportId && reportJson(reportId, userPtr.objectId); const clsName = 'contracts_Document'; if (reportId && json) { const { params, keys } = json; @@ -57,6 +63,13 @@ export default async function getDocumentList(request, response) { const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr`; const res = await axios.get(url, { headers: headers }); if (res.data && res.data.results.length > 0) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_document_list_by_status', + properties: { response_code: 200 }, + }); + } const updateRes = res.data.results.map(x => ({ objectId: x.objectId, title: x.Name, @@ -74,6 +87,13 @@ export default async function getDocumentList(request, response) { return response.json({ result: [] }); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_document_list_by_status', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Report not available!' }); } } diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplate.js index ab56f2b36..818fb7223 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplate.js @@ -6,10 +6,17 @@ export default async function getTemplate(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; + const Template = new Parse.Query('contracts_Template'); Template.equalTo('objectId', request.params.template_id); Template.equalTo('CreatedBy', userPtr); @@ -20,6 +27,14 @@ export default async function getTemplate(request, response) { const res = await Template.first({ useMasterKey: true }); if (res) { const template = JSON.parse(JSON.stringify(res)); + + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_template', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: template.objectId, title: template.Name, @@ -34,6 +49,13 @@ export default async function getTemplate(request, response) { updatedAt: template.updatedAt, }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_template', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Template not found!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplateList.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplateList.js index 435e99f73..6d4d5e978 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplateList.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getTemplateList.js @@ -1,7 +1,6 @@ import axios from 'axios'; import dotenv from 'dotenv'; dotenv.config(); - export default async function getTemplatetList(request, response) { const reqToken = request.headers['x-api-token']; const appId = process.env.APP_ID; @@ -11,21 +10,24 @@ export default async function getTemplatetList(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; + const limit = request?.query?.limit ? request.query.limit : 100; const skip = request?.query?.skip ? request.query.skip : 0; const clsName = 'contracts_Template'; const params = { Type: { $ne: 'Folder' }, - CreatedBy: { - __type: 'Pointer', - className: '_User', - objectId: userPtr.id, - }, + CreatedBy: userPtr, IsArchive: { $ne: true }, }; const keys = [ @@ -51,6 +53,13 @@ export default async function getTemplatetList(request, response) { const url = `${serverUrl}/classes/${clsName}?where=${strParams}&keys=${strKeys}&order=${orderBy}&skip=${skip}&limit=${limit}&include=AuditTrail.UserPtr`; const res = await axios.get(url, { headers: headers }); if (res.data && res.data.results.length > 0) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_template_list', + properties: { response_code: 200 }, + }); + } const updateRes = res.data.results.map(x => ({ objectId: x.objectId, title: x.Name, @@ -65,6 +74,13 @@ export default async function getTemplatetList(request, response) { return response.json({ result: updateRes }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_template_list', + properties: { response_code: 200 }, + }); + } return response.json({ result: [] }); } } diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getUser.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getUser.js index 81da0d479..b1e9b25df 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/getUser.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getUser.js @@ -8,16 +8,30 @@ export default async function getUser(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; + const query = new Parse.Query('contracts_Users'); query.equalTo('UserId', userPtr); query.exclude('IsContactEntry,TourStatus,UserRole,TenantId,UserId,CreatedBy,Plan'); const user = await query.first({ useMasterKey: true }); if (user) { const parseRes = JSON.parse(JSON.stringify(user)); + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_your_account_details', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: parseRes.objectId, name: parseRes.Name, @@ -29,6 +43,13 @@ export default async function getUser(request, response) { updatedAt: parseRes.updatedAt, }); } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_your_account_details', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'User not found!' }); } } diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/getWebhook.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/getWebhook.js index 244965e2b..2b3c73ee6 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/getWebhook.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/getWebhook.js @@ -5,16 +5,28 @@ export default async function getWebhook(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; const query = new Parse.Query('contracts_Users'); query.equalTo('UserId', userPtr); const user = await query.first({ useMasterKey: true }); if (user) { const parseUser = JSON.parse(JSON.stringify(user)); - + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_webhook', + properties: { response_code: 200 }, + }); + } if (parseUser && parseUser.Webhook) { return response.json({ webhook: parseUser.Webhook, @@ -23,6 +35,13 @@ export default async function getWebhook(request, response) { return response.json({}); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'get_webhook', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'User not found!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/saveWebhook.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/saveWebhook.js index bbb2be945..caff3d8ce 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/saveWebhook.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/saveWebhook.js @@ -6,10 +6,16 @@ export default async function saveWebhook(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request - const userPtr = token.get('userId'); + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; const query = new Parse.Query('contracts_Users'); query.equalTo('UserId', userPtr); const user = await query.first({ useMasterKey: true }); @@ -24,23 +30,52 @@ export default async function saveWebhook(request, response) { updateQuery.set('Webhook', Url); const res = await updateQuery.save(null, { useMasterKey: true }); if (res) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'save_webhook', + properties: { response_code: 200 }, + }); + } return response.json({ result: 'Webhook updated successfully!', }); } } catch (err) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'save_webhook', + properties: { response_code: 400 }, + }); + } console.log('Err ', err); return response .status(400) .json({ error: 'Something went wrong, please try again later!' }); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'save_webhook', + properties: { response_code: 401 }, + }); + } return response.status(401).json({ error: 'Webhook url already exists!' }); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'save_webhook', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'User not found!' }); } } else { return response.status(405).json({ error: 'Invalid API Token!' }); } } +// client.shutdown() diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/updateDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/updateDocument.js index 51fda1139..bdd98690c 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/updateDocument.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/updateDocument.js @@ -6,14 +6,20 @@ export default async function updateDocument(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request const allowedKeys = ['name', 'note', 'description']; const objectKeys = Object.keys(request.body); const isValid = objectKeys.every(key => allowedKeys.includes(key)) && objectKeys.length > 0; + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; if (isValid) { - const userPtr = token.get('userId'); const document = new Parse.Query('contracts_Document'); document.equalTo('objectId', request.params.document_id); document.equalTo('CreatedBy', userPtr); @@ -44,6 +50,13 @@ export default async function updateDocument(request, response) { } const updatedRes = await updateQuery.save(null, { useMasterKey: true }); if (updatedRes) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'update_document', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: updatedRes.id, updatedAt: updatedRes.get('updatedAt'), @@ -51,9 +64,23 @@ export default async function updateDocument(request, response) { } } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'update_document', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Document not found!' }); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'update_document', + properties: { response_code: 400 }, + }); + } return response.status(400).json({ error: 'Please provide valid field names!' }); } } else { diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/updateTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/updateTemplate.js index 7bbe031b2..ab3405c29 100644 --- a/apps/OpenSignServer/cloud/customRoute/v1/routes/updateTemplate.js +++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/updateTemplate.js @@ -6,14 +6,20 @@ export default async function updateTemplate(request, response) { } const tokenQuery = new Parse.Query('appToken'); tokenQuery.equalTo('token', reqToken); + tokenQuery.include('userId'); const token = await tokenQuery.first({ useMasterKey: true }); if (token !== undefined) { // Valid Token then proceed request const allowedKeys = ['name', 'note', 'description']; const objectKeys = Object.keys(request.body); const isValid = objectKeys.every(key => allowedKeys.includes(key)) && objectKeys.length > 0; + const parseUser = JSON.parse(JSON.stringify(token)); + const userPtr = { + __type: 'Pointer', + className: '_User', + objectId: parseUser.userId.objectId, + }; if (isValid) { - const userPtr = token.get('userId'); const template = new Parse.Query('contracts_Template'); template.equalTo('objectId', request.params.template_id); template.equalTo('CreatedBy', userPtr); @@ -44,6 +50,13 @@ export default async function updateTemplate(request, response) { } const updatedRes = await updateQuery.save(null, { useMasterKey: true }); if (updatedRes) { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'update_template', + properties: { response_code: 200 }, + }); + } return response.json({ objectId: updatedRes.id, updatedAt: updatedRes.get('updatedAt'), @@ -51,9 +64,23 @@ export default async function updateTemplate(request, response) { } } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'update_template', + properties: { response_code: 404 }, + }); + } return response.status(404).json({ error: 'Template not found!' }); } } else { + if (request.posthog) { + request.posthog?.capture({ + distinctId: parseUser.userId.email, + event: 'update_template', + properties: { response_code: 400 }, + }); + } return response.status(400).json({ error: 'Please provide valid field names!' }); } } else { diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js index 28d63e64a..07da66812 100644 --- a/apps/OpenSignServer/index.js +++ b/apps/OpenSignServer/index.js @@ -20,7 +20,7 @@ import { app as customRoute } from './cloud/customRoute/customApp.js'; import { exec } from 'child_process'; import { createTransport } from 'nodemailer'; import { app as v1 } from './cloud/customRoute/v1/apiV1.js'; - +import { PostHog } from 'posthog-node'; const spacesEndpoint = new AWS.Endpoint(process.env.DO_ENDPOINT); // console.log("configuration ", configuration); if (process.env.USE_LOCAL !== 'TRUE') { @@ -154,6 +154,16 @@ function getUserIP(request) { return request.socket.remoteAddress; } } +app.use(function (req, res, next) { + const ph_project_api_key = process.env.PH_PROJECT_API_KEY; + try { + req.posthog = new PostHog(ph_project_api_key); + } catch (err) { + // console.log('Err', err); + req.posthog = ''; + } + next(); +}); // Serve static assets from the /public folder app.use('/public', express.static(path.join(__dirname, '/public'))); diff --git a/apps/OpenSignServer/package-lock.json b/apps/OpenSignServer/package-lock.json index fac7ba41c..119072cf3 100644 --- a/apps/OpenSignServer/package-lock.json +++ b/apps/OpenSignServer/package-lock.json @@ -35,6 +35,7 @@ "parse-server-s3-adapter": "^1.2.0", "pdf-lib": "^1.16.0", "pdfkit": "^0.13.0", + "posthog-node": "^3.6.2", "razorpay": "^2.8.6", "request": "^2.88.2" }, @@ -8373,6 +8374,47 @@ "node": ">=0.10.0" } }, + "node_modules/posthog-node": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-3.6.2.tgz", + "integrity": "sha512-tVIaShR3SxBx17AlAUS86jQTweKuJIFRedBB504fCz7YPnXJTYSrVcUHn5IINE2wu4jUQimQK6ihQr90Djrdrg==", + "dependencies": { + "axios": "^1.6.2", + "rusha": "^0.8.14" + }, + "engines": { + "node": ">=15.0.0" + } + }, + "node_modules/posthog-node/node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/posthog-node/node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/precond": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", @@ -8870,6 +8912,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rusha": { + "version": "0.8.14", + "resolved": "https://registry.npmjs.org/rusha/-/rusha-0.8.14.tgz", + "integrity": "sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==" + }, "node_modules/safari-14-idb-fix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/safari-14-idb-fix/-/safari-14-idb-fix-3.0.0.tgz", diff --git a/apps/OpenSignServer/package.json b/apps/OpenSignServer/package.json index 350f10979..de0fa18b4 100644 --- a/apps/OpenSignServer/package.json +++ b/apps/OpenSignServer/package.json @@ -44,6 +44,7 @@ "parse-server-s3-adapter": "^1.2.0", "pdf-lib": "^1.16.0", "pdfkit": "^0.13.0", + "posthog-node": "^3.6.2", "razorpay": "^2.8.6", "request": "^2.88.2" },