{Object.keys(actLoader)?.length > 0 && (
@@ -562,18 +579,14 @@ const ReportTable = (props) => {
)}
- handleDownload(item)}
+ className="text-[blue] hover:text-[blue] hover:underline focus:outline-none"
+ title={"Download"}
>
{item?.URL ? "Download" : "-"}
-
+
|
-
{formatRow(item?.ExtUserPtr)}
|
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js
index b3b6f2179..1e2e0bc9a 100644
--- a/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/CreateDocumentWithTemplate.js
@@ -217,9 +217,10 @@ export default async function createDocumentWithTemplate(request, response) {
};
const objectId = contactMail[i].contactPtr.objectId;
-
const hostUrl = baseUrl.origin;
- let signPdf = `${hostUrl}/login/${res.id}/${contactMail[i].email}/${objectId}/${serverParams}`;
+ //encode this url value `${res.id}/${contactMail[i].email}/${objectId}` to base64 using `btoa` function
+ const encodeBase64 = btoa(`${res.id}/${contactMail[i].email}/${objectId}`);
+ let signPdf = `${hostUrl}/login/${encodeBase64}`;
const openSignUrl = 'https://www.opensignlabs.com/contact-us';
const orgName = template.ExtUserPtr.Company ? template.ExtUserPtr.Company : '';
const themeBGcolor = '#47a3ad';
@@ -266,13 +267,13 @@ export default async function createDocumentWithTemplate(request, response) {
replaceVar = { subject: replaceVar.subject, body: email_html };
} else if (email_body) {
replaceVar = replaceMailVaribles(
- `${template.ExtUserPtr.Name} has requested you to sign ${template.Name}`,
+ `${template.ExtUserPtr.Name} has requested you to sign "${template.Name}"`,
email_body,
variables
);
} else {
replaceVar = {
- subject: `${template.ExtUserPtr.Name} has requested you to sign ${template.Name}`,
+ subject: `${template.ExtUserPtr.Name} has requested you to sign "${template.Name}"`,
body: email_html,
};
}
@@ -320,7 +321,9 @@ export default async function createDocumentWithTemplate(request, response) {
objectId: res.id,
signurl: contact.map(x => ({
email: x.email,
- url: `${baseUrl.origin}/login/${res.id}/${x.email}/${x.contactPtr.objectId}/${serverParams}`,
+ url: `${baseUrl.origin}/login/${btoa(
+ `${res.id}/${x.email}/${x.contactPtr.objectId}`
+ )}`,
})),
message: 'Document sent successfully!',
});
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js
index f6656f6fb..68f911ed7 100644
--- a/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/createDocumentwithCoordinate.js
@@ -278,7 +278,9 @@ export default async function createDocumentwithCoordinate(request, response) {
const objectId = contactMail[i].contactPtr.objectId;
const hostUrl = baseUrl.origin;
- let signPdf = `${hostUrl}/login/${res.id}/${contactMail[i].email}/${objectId}/${serverParams}`;
+ //encode this url value `${response.id}/${contactMail[i].email}/${objectId}` to base64 using `btoa` function
+ const encodeBase64 = btoa(`${response.id}/${contactMail[i].email}/${objectId}`);
+ let signPdf = `${hostUrl}/login/${encodeBase64}`;
const openSignUrl = 'https://www.opensignlabs.com/contact-us';
const orgName = parseExtUser.Company ? parseExtUser.Company : '';
const themeBGcolor = '#47a3ad';
@@ -324,13 +326,13 @@ export default async function createDocumentwithCoordinate(request, response) {
replaceVar = { subject: replaceVar.subject, body: email_html };
} else if (email_body) {
replaceVar = replaceMailVaribles(
- `${parseExtUser.Name} has requested you to sign ${name}`,
+ `${parseExtUser.Name} has requested you to sign "${name}"`,
email_body,
variables
);
} else {
replaceVar = {
- subject: `${parseExtUser.Name} has requested you to sign ${parseExtUser.Name}`,
+ subject: `${parseExtUser.Name} has requested you to sign "${parseExtUser.Name}"`,
body: email_html,
};
}
@@ -363,7 +365,7 @@ export default async function createDocumentwithCoordinate(request, response) {
objectId: res.id,
signurl: contact.map(x => ({
email: x.email,
- url: `${baseUrl.origin}/login/${res.id}/${x.email}/${x.contactPtr.objectId}/${serverParams}`,
+ url: `${baseUrl.origin}/login/${btoa(`${res.id}/${x.email}/${x.contactPtr.objectId}`)}`,
})),
message: 'Document sent successfully!',
});
diff --git a/apps/OpenSignServer/cloud/customRoute/v1/routes/draftDocument.js b/apps/OpenSignServer/cloud/customRoute/v1/routes/draftDocument.js
index 7f31b66bc..7651c580e 100644
--- a/apps/OpenSignServer/cloud/customRoute/v1/routes/draftDocument.js
+++ b/apps/OpenSignServer/cloud/customRoute/v1/routes/draftDocument.js
@@ -1,5 +1,5 @@
import axios from 'axios';
-import { customAPIurl } from '../../../../Utils.js';
+import { customAPIurl, saveFileUsage } from '../../../../Utils.js';
// const randomId = () => Math.floor(1000 + Math.random() * 9000);
export default async function draftDocument(request, response) {
diff --git a/apps/OpenSignServer/cloud/main.js b/apps/OpenSignServer/cloud/main.js
index 1833e2d30..bc6cb66a2 100644
--- a/apps/OpenSignServer/cloud/main.js
+++ b/apps/OpenSignServer/cloud/main.js
@@ -33,7 +33,10 @@ import getInvoices from './parsefunction/getInvoices.js';
import getPayments from './parsefunction/getPayments.js';
import getSubscriptions from './parsefunction/getSubscriptions.js';
import TenantAterFind from './parsefunction/TenantAfterFind.js';
-import saveSubscriptio from './parsefunction/saveSubscription.js';
+import saveSubscription from './parsefunction/saveSubscription.js';
+import VerifyEmail from './parsefunction/VerifyEmail.js';
+import encryptedpdf from './parsefunction/encryptedPdf.js';
+import { getSignedUrl } from './parsefunction/getSignedUrl.js';
Parse.Cloud.define('AddUserToRole', addUserToGroups);
Parse.Cloud.define('UserGroups', getUserGroups);
@@ -70,4 +73,7 @@ Parse.Cloud.afterFind('contracts_Document', DocumentBeforeFind);
Parse.Cloud.afterFind('contracts_Template', TemplateAfterFind);
Parse.Cloud.afterFind('contracts_Signature', SignatureAfterFind);
Parse.Cloud.afterFind('partners_Tenant', TenantAterFind);
-Parse.Cloud.define('savesubscription', saveSubscriptio);
+Parse.Cloud.define('savesubscription', saveSubscription);
+Parse.Cloud.define('verifyemail', VerifyEmail);
+Parse.Cloud.define('encryptedpdf', encryptedpdf);
+Parse.Cloud.define('getsignedurl', getSignedUrl);
diff --git a/apps/OpenSignServer/cloud/parsefunction/DocumentAftersave.js b/apps/OpenSignServer/cloud/parsefunction/DocumentAftersave.js
index dc26a3e09..fe8744873 100644
--- a/apps/OpenSignServer/cloud/parsefunction/DocumentAftersave.js
+++ b/apps/OpenSignServer/cloud/parsefunction/DocumentAftersave.js
@@ -4,6 +4,7 @@ async function DocumentAftersave(request) {
console.log('new entry is insert in contracts_Document');
const createdAt = request.object.get('createdAt');
const Folder = request.object.get('Type');
+ const ip = request?.headers?.['x-real-ip'] || '';
if (createdAt && Folder === undefined) {
// console.log("IN If condition")
const TimeToCompleteDays = request.object.get('TimeToCompleteDays');
@@ -12,6 +13,7 @@ async function DocumentAftersave(request) {
const documentQuery = new Parse.Query('contracts_Document');
const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true });
updateQuery.set('ExpiryDate', ExpiryDate);
+ updateQuery.set('OriginIp', ip);
await updateQuery.save(null, { useMasterKey: true });
} else if (createdAt && Folder === 'AIDoc') {
const TimeToCompleteDays = request.object.get('TimeToCompleteDays');
@@ -24,6 +26,7 @@ async function DocumentAftersave(request) {
const documentQuery = new Parse.Query('contracts_Document');
const updateQuery = await documentQuery.get(request.object.id, { useMasterKey: true });
updateQuery.set('ExpiryDate', ExpiryDate);
+ updateQuery.set('OriginIp', ip);
await updateQuery.save(null, { useMasterKey: true });
}
diff --git a/apps/OpenSignServer/cloud/parsefunction/DocumentBeforesave.js b/apps/OpenSignServer/cloud/parsefunction/DocumentBeforesave.js
index 0effff5ec..e7f251ca4 100644
--- a/apps/OpenSignServer/cloud/parsefunction/DocumentBeforesave.js
+++ b/apps/OpenSignServer/cloud/parsefunction/DocumentBeforesave.js
@@ -25,6 +25,10 @@ async function DocumentBeforesave(request) {
} catch (error) {
console.log('Error updating document count in contracts_users: ' + error.message);
}
+ if (document?.get('Signers') && document.get('Signers').length > 0) {
+ document.set('DocSentAt', new Date());
+ document.save(null, { useMasterKey: true });
+ }
}
} catch (err) {
console.log('err in document beforesave', err.message);
diff --git a/apps/OpenSignServer/cloud/parsefunction/VerifyEmail.js b/apps/OpenSignServer/cloud/parsefunction/VerifyEmail.js
new file mode 100644
index 000000000..8c1f08d32
--- /dev/null
+++ b/apps/OpenSignServer/cloud/parsefunction/VerifyEmail.js
@@ -0,0 +1,49 @@
+export default async function VerifyEmail(request) {
+ try {
+ if (!request?.user) {
+ throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
+ } else {
+ let otpN = request.params.otp;
+ let otp = parseInt(otpN);
+ let email = request.params.email;
+
+ //checking otp is correct or not which already save in defaultdata_Otp class
+ const checkOtp = new Parse.Query('defaultdata_Otp');
+ checkOtp.equalTo('Email', email);
+ checkOtp.equalTo('OTP', otp);
+
+ const res = await checkOtp.first({ useMasterKey: true });
+ if (res) {
+ // Fetch the user by their objectId
+ const isEmailVerified = request?.user?.get('emailVerified');
+ if (isEmailVerified) {
+ return { message: 'Email is already verified.' };
+ } else {
+ const userQuery = new Parse.Query(Parse.User);
+ const user = await userQuery.get(request?.user.id, {
+ sessionToken: request?.user.getSessionToken(),
+ });
+
+ // Update the emailVerified field to true
+ user.set('emailVerified', true);
+ // Save the user object
+ const res = await user.save(null, { useMasterKey: true });
+ if (res) {
+ return { message: 'Email is verified.' };
+ } else {
+ const error = new Error('Something went wrong, please try again later!');
+ error.code = 400; // Set the error code (e.g., 400 for bad request)
+ throw error;
+ }
+ }
+ } else {
+ const error = new Error('OTP is invalid.');
+ error.code = 400; // Set the error code (e.g., 400 for bad request)
+ throw error;
+ }
+ }
+ } catch (err) {
+ console.log('err ', err.code + ' ' + err.message);
+ throw err;
+ }
+}
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/encryptedPdf.js b/apps/OpenSignServer/cloud/parsefunction/encryptedPdf.js
new file mode 100644
index 000000000..315cf737b
--- /dev/null
+++ b/apps/OpenSignServer/cloud/parsefunction/encryptedPdf.js
@@ -0,0 +1,14 @@
+import { PostHog } from 'posthog-node';
+const ph_project_api_key = process.env.PH_PROJECT_API_KEY;
+const client = ph_project_api_key ? new PostHog(ph_project_api_key) : '';
+export default async function encryptedpdf(request) {
+ const email = request.params.email;
+ if (client) {
+ client?.capture({
+ distinctId: email,
+ event: 'encrypted_pdf_error',
+ properties: { response_code: 200 },
+ });
+ }
+ return { message: 'success' };
+}
diff --git a/apps/OpenSignServer/cloud/parsefunction/getSignedUrl.js b/apps/OpenSignServer/cloud/parsefunction/getSignedUrl.js
index d2869b549..642b41fdd 100644
--- a/apps/OpenSignServer/cloud/parsefunction/getSignedUrl.js
+++ b/apps/OpenSignServer/cloud/parsefunction/getSignedUrl.js
@@ -1,4 +1,5 @@
import AWS from 'aws-sdk';
+import { useLocal } from '../../Utils.js';
const credentials = {
accessKeyId: process.env.DO_ACCESS_KEY_ID,
secretAccessKey: process.env.DO_SECRET_ACCESS_KEY,
@@ -24,3 +25,25 @@ export default function getPresignedUrl(url) {
});
return presignedGETURL;
}
+
+export async function getSignedUrl(request) {
+ try {
+ const url = request.params.url;
+ if (!request?.user) {
+ throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
+ } else {
+ if (useLocal !== 'true') {
+ const presignedUrl = getPresignedUrl(url);
+ return presignedUrl;
+ } else {
+ return url;
+ }
+ }
+ } catch (err) {
+ console.log('error in getsignedurl', err);
+ const code = err.code || 400;
+ const msg = err.message;
+ const error = new Parse.Error(code, msg);
+ throw error;
+ }
+}
diff --git a/apps/OpenSignServer/cloud/parsefunction/pdf/GenerateCertificate.js b/apps/OpenSignServer/cloud/parsefunction/pdf/GenerateCertificate.js
index 2b9b7625f..0845e7fbd 100644
--- a/apps/OpenSignServer/cloud/parsefunction/pdf/GenerateCertificate.js
+++ b/apps/OpenSignServer/cloud/parsefunction/pdf/GenerateCertificate.js
@@ -15,23 +15,44 @@ export default async function GenerateCertificate(docDetails) {
const title = 25;
const subtitle = 20;
const text = 14;
+ const timeText = 11;
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 OriginIp = docDetails?.OriginIp || '';
const company = docDetails?.ExtUserPtr?.Company || '';
+ const createdAt = docDetails?.DocSentAt?.iso || docDetails.createdAt;
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 || x?.SignedOn || 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 ||
+ docDetails?.AuditTrail[0]?.SignedOn ||
+ generatedUTCTime,
+ Signature: docDetails?.AuditTrail[0]?.Signature || '',
+ },
+ ];
+ const half = width / 2;
// Draw a border
page.drawRectangle({
x: startX,
@@ -48,7 +69,7 @@ export default async function GenerateCertificate(docDetails) {
height: 25,
});
- page.drawText(createDate, {
+ page.drawText(generatedOn, {
x: 320,
y: 810,
size: 12,
@@ -127,8 +148,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 +156,14 @@ export default async function GenerateCertificate(docDetails) {
color: textKeyColor,
});
- page.drawText(`${completedUTCtime}`, {
- x: 120,
+ page.drawText(`${new Date(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 +171,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(`${OriginIp}`, {
+ 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,15 +274,31 @@ 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 +55,
+ y: yPosition2,
+ size: timeText,
+ font: timesRomanFont,
+ color: textKeyColor,
+ });
+
+ page.drawText(`${new Date(x.ViewedOn).toUTCString()}`, {
+ x: half + 112,
+ y: yPosition2,
+ size: timeText,
+ font: timesRomanFont,
+ color: textValueColor,
+ });
+
page.drawText('Email :', {
x: 30,
- y: yPosition2,
+ y: yPosition3,
size: text,
font: timesRomanFont,
color: textKeyColor,
@@ -204,41 +306,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 :', {
+ page.drawText('Signed on :', {
+ x: half + 55,
+ y: yPosition3 + 5,
+ size: timeText,
+ font: timesRomanFont,
+ color: textKeyColor,
+ });
+
+ page.drawText(`${new Date(x.SignedOn).toUTCString()}`, {
+ x: half + 108,
+ y: yPosition3 + 5,
+ size: timeText,
+ font: timesRomanFont,
+ color: textValueColor,
+ });
+
+ page.drawText('IP address :', {
x: 30,
- y: yPosition3,
+ y: yPosition4,
size: text,
font: timesRomanFont,
color: textKeyColor,
});
page.drawText(x?.ipAddress, {
- x: 125,
- y: yPosition3,
- size: text,
+ x: 100,
+ y: yPosition4,
+ size: 13,
+ font: timesRomanFont,
+ color: textValueColor,
+ });
+ page.drawText('Security level :', {
+ x: half + 55,
+ y: yPosition4 + 10,
+ size: timeText,
+ font: timesRomanFont,
+ color: textKeyColor,
+ });
+
+ page.drawText(`Email, OTP Auth`, {
+ x: half + 125,
+ y: yPosition4 + 10,
+ size: timeText,
font: timesRomanFont,
color: textValueColor,
});
+ page.drawText('Signature :', {
+ x: 30,
+ y: yPosition5,
+ size: text,
+ font: timesRomanFont,
+ color: textKeyColor,
+ });
+
+ page.drawRectangle({
+ x: 98,
+ y: yPosition5 - 30,
+ width: 104,
+ height: 44,
+ borderColor: rgb(0.22, 0.18, 0.47),
+ borderWidth: 1,
+ });
+ if (embedPng) {
+ page.drawImage(embedPng, {
+ x: 100,
+ y: yPosition5 - 27,
+ 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.ViewedOn).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..fec7ab4ef 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 in signpdf', e), e);
}
}
export default PDF;
diff --git a/apps/OpenSignServer/cloud/parsefunction/saveSubscription.js b/apps/OpenSignServer/cloud/parsefunction/saveSubscription.js
index 9b1e262f6..2771e81c4 100644
--- a/apps/OpenSignServer/cloud/parsefunction/saveSubscription.js
+++ b/apps/OpenSignServer/cloud/parsefunction/saveSubscription.js
@@ -1,5 +1,5 @@
import axios from 'axios';
-export default async function saveSubscriptio(request) {
+export default async function saveSubscription(request) {
const serverUrl = process.env.SERVER_URL;
const appId = process.env.APP_ID;
const subscription = request.params.subscription;
diff --git a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js
index c09694a4d..7a8b2e6f8 100644
--- a/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js
+++ b/apps/OpenSignServer/cloud/parsefunction/sendMailv3.js
@@ -4,6 +4,7 @@ import formData from 'form-data';
import Mailgun from 'mailgun.js';
import { updateMailCount } from '../../Utils.js';
import sendMailGmailProvider from './sendMailGmailProvider.js';
+import { createTransport } from 'nodemailer';
async function sendMailProvider(req) {
try {
let transporterSMTP;
diff --git a/apps/OpenSignServer/index.js b/apps/OpenSignServer/index.js
index a9432da6b..d6ba7ad9b 100644
--- a/apps/OpenSignServer/index.js
+++ b/apps/OpenSignServer/index.js
@@ -166,11 +166,6 @@ app.use(cors());
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb', extended: true }));
app.use(function (req, res, next) {
- // console.log("req ", req.headers);
- // console.log("x-forwarded-for", req.headers["x-forwarded-for"]);
- // console.log("req.ip", req.ip);
- // console.log("req.socket.remoteAddress; ", req.socket.remoteAddress);
- // console.log("ip", ip.address());
req.headers['x-real-ip'] = getUserIP(req);
next();
});
@@ -230,7 +225,7 @@ if (!process.env.TESTING) {
// Set the Keep-Alive and headers timeout to 100 seconds
httpServer.keepAliveTimeout = 100000; // in milliseconds
httpServer.headersTimeout = 100000; // in milliseconds
- httpServer.listen(port, function () {
+ httpServer.listen(port, '0.0.0.0', function () {
console.log('parse-server-example running on port ' + port + '.');
const isWindows = process.platform === 'win32';
// console.log('isWindows', isWindows);
diff --git a/apps/OpenSignServer/package-lock.json b/apps/OpenSignServer/package-lock.json
index 4d464842a..ba80c14a1 100644
--- a/apps/OpenSignServer/package-lock.json
+++ b/apps/OpenSignServer/package-lock.json
@@ -14,19 +14,19 @@
"axios": "^1.6.8",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
- "express": "^4.18.3",
+ "express": "^4.19.2",
"express-sse": "^0.5.3",
"form-data": "^4.0.0",
"generate-api-key": "^1.0.2",
"googleapis": "^134.0.0",
"jsonschema": "^1.4.1",
"mailgun.js": "^10.2.1",
- "mongoose": "^8.2.2",
+ "mongoose": "^8.3.3",
"multer": "^1.4.5-lts.1",
"multer-s3": "^3.0.1",
"node-forge": "^1.3.1",
"node-signpdf": "^1.5.1",
- "nodemailer": "^6.9.12",
+ "nodemailer": "^6.9.13",
"parse": "^5.0.0",
"parse-dbtool": "^1.2.0",
"parse-server": "^6.5.5",
@@ -4123,9 +4123,9 @@
}
},
"node_modules/bson": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz",
- "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-6.7.0.tgz",
+ "integrity": "sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==",
"engines": {
"node": ">=16.20.1"
}
@@ -7595,9 +7595,9 @@
}
},
"node_modules/kareem": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz",
- "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==",
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz",
+ "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==",
"engines": {
"node": ">=12.0.0"
}
@@ -7961,12 +7961,12 @@
}
},
"node_modules/mongodb": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz",
- "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz",
+ "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==",
"dependencies": {
- "@mongodb-js/saslprep": "^1.1.0",
- "bson": "^6.2.0",
+ "@mongodb-js/saslprep": "^1.1.5",
+ "bson": "^6.4.0",
"mongodb-connection-string-url": "^3.0.0"
},
"engines": {
@@ -8312,13 +8312,13 @@
}
},
"node_modules/mongoose": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.2.tgz",
- "integrity": "sha512-6sMxe1d3k/dBjiOX4ExNTNOP0g1x0iq8eXyg+ttgIXM3HLnQ0IUyXRwVVAPFFY6O4/8uYN5dB0Ec72FrexbPpw==",
+ "version": "8.3.3",
+ "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.3.3.tgz",
+ "integrity": "sha512-3kSk0db9DM2tLttCdS6WNRqewPleamFEa4Vz/Qldc0dB4Zow/FiZxb9GExHTJjBZQ9T2xiGleQ3GzRrES3hhsA==",
"dependencies": {
- "bson": "^6.2.0",
- "kareem": "2.5.1",
- "mongodb": "6.3.0",
+ "bson": "^6.5.0",
+ "kareem": "2.6.3",
+ "mongodb": "6.5.0",
"mpath": "0.9.0",
"mquery": "5.0.0",
"ms": "2.1.3",
@@ -8503,9 +8503,9 @@
}
},
"node_modules/nodemailer": {
- "version": "6.9.12",
- "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.12.tgz",
- "integrity": "sha512-pnLo7g37Br3jXbF0bl5DekBJihm2q+3bB3l2o/B060sWmb5l+VqeScAQCBqaQ+5ezRZFzW5SciZNGdRDEbq89w==",
+ "version": "6.9.13",
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.13.tgz",
+ "integrity": "sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA==",
"engines": {
"node": ">=6.0.0"
}
diff --git a/apps/OpenSignServer/package.json b/apps/OpenSignServer/package.json
index f3773756c..e1546c204 100644
--- a/apps/OpenSignServer/package.json
+++ b/apps/OpenSignServer/package.json
@@ -23,19 +23,19 @@
"axios": "^1.6.8",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
- "express": "^4.18.3",
+ "express": "^4.19.2",
"express-sse": "^0.5.3",
"form-data": "^4.0.0",
"generate-api-key": "^1.0.2",
"googleapis": "^134.0.0",
"jsonschema": "^1.4.1",
"mailgun.js": "^10.2.1",
- "mongoose": "^8.2.2",
+ "mongoose": "^8.3.3",
"multer": "^1.4.5-lts.1",
"multer-s3": "^3.0.1",
"node-forge": "^1.3.1",
"node-signpdf": "^1.5.1",
- "nodemailer": "^6.9.12",
+ "nodemailer": "^6.9.13",
"parse": "^5.0.0",
"parse-dbtool": "^1.2.0",
"parse-server": "^6.5.5",