mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-22 23:52:30 +02:00
Fix: Document title changes are not reflected when the document is sent to signers.
Merge pull request #1498 from nxglabs/staging
This commit is contained in:
@@ -41,6 +41,7 @@ export default async function GenerateCertificate(docDetails) {
|
||||
const maxX = width - margin - textWidth; // Ensures text stays inside the border with 30px margin
|
||||
const OriginIp = docDetails?.OriginIp || '';
|
||||
const company = docDetails?.ExtUserPtr?.Company || '';
|
||||
const documentHash = docDetails?.DocumentHash || '';
|
||||
const createdAt = docDetails?.DocSentAt?.iso || docDetails.createdAt;
|
||||
const createdAtperTimezone = formatDateTime(createdAt, DateFormat, timezone, Is12Hr);
|
||||
const IsEnableOTP = docDetails?.IsEnableOTP || false;
|
||||
@@ -150,9 +151,36 @@ export default async function GenerateCertificate(docDetails) {
|
||||
color: textValueColor,
|
||||
});
|
||||
|
||||
if (documentHash) {
|
||||
page.drawText('Document hash (sha256) :', {
|
||||
x: 30,
|
||||
y: 670,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
});
|
||||
|
||||
page.drawText(documentHash, {
|
||||
x: 170,
|
||||
y: 670,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
}
|
||||
|
||||
const organizationY = documentHash ? 650 : 670;
|
||||
const createdOnY = organizationY - 20;
|
||||
const completedOnY = createdOnY - 20;
|
||||
const signersY = completedOnY - 20;
|
||||
const originatorHeaderY = signersY - 20;
|
||||
const nameY = originatorHeaderY - 17;
|
||||
const emailY = nameY - 20;
|
||||
const ipY = emailY - 20;
|
||||
|
||||
page.drawText('Organization :', {
|
||||
x: 30,
|
||||
y: 670,
|
||||
y: organizationY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
@@ -160,14 +188,14 @@ export default async function GenerateCertificate(docDetails) {
|
||||
|
||||
page.drawText(company, {
|
||||
x: 110,
|
||||
y: 670,
|
||||
y: organizationY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
page.drawText('Created on :', {
|
||||
x: 30,
|
||||
y: 650,
|
||||
y: createdOnY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
@@ -175,14 +203,14 @@ export default async function GenerateCertificate(docDetails) {
|
||||
|
||||
page.drawText(`${createdAtperTimezone}`, {
|
||||
x: 97,
|
||||
y: 650,
|
||||
y: createdOnY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
page.drawText('Completed on :', {
|
||||
x: 30,
|
||||
y: 630,
|
||||
y: completedOnY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
@@ -190,14 +218,14 @@ export default async function GenerateCertificate(docDetails) {
|
||||
|
||||
page.drawText(`${completedUTCtime}`, {
|
||||
x: 115,
|
||||
y: 630,
|
||||
y: completedOnY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
page.drawText('Signers :', {
|
||||
x: 30,
|
||||
y: 610,
|
||||
y: signersY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
@@ -205,75 +233,75 @@ export default async function GenerateCertificate(docDetails) {
|
||||
|
||||
page.drawText(`${signersCount}`, {
|
||||
x: 80,
|
||||
y: 610,
|
||||
y: signersY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
page.drawText('Document originator', {
|
||||
x: 30,
|
||||
y: 590,
|
||||
y: originatorHeaderY,
|
||||
size: 17,
|
||||
font: timesRomanFont,
|
||||
color: titleColor,
|
||||
});
|
||||
page.drawText('Name :', {
|
||||
x: 60,
|
||||
y: 573,
|
||||
y: nameY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
});
|
||||
page.drawText(ownerName, {
|
||||
x: 105,
|
||||
y: 573,
|
||||
y: nameY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
page.drawText('Email :', {
|
||||
x: 60,
|
||||
y: 553,
|
||||
y: emailY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
});
|
||||
page.drawText(ownerEmail, {
|
||||
x: 105,
|
||||
y: 553,
|
||||
y: emailY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
page.drawText('IP address :', {
|
||||
x: 60,
|
||||
y: 533,
|
||||
y: ipY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textKeyColor,
|
||||
});
|
||||
page.drawText(`${OriginIp}`, {
|
||||
x: 125,
|
||||
y: 533,
|
||||
y: ipY,
|
||||
size: text,
|
||||
font: timesRomanFont,
|
||||
color: textValueColor,
|
||||
});
|
||||
|
||||
page.drawLine({
|
||||
start: { x: 30, y: 527 },
|
||||
end: { x: width - 30, y: 527 },
|
||||
start: { x: 30, y: ipY - 6 },
|
||||
end: { x: width - 30, y: ipY - 6 },
|
||||
color: rgb(0.12, 0.12, 0.12),
|
||||
thickness: 0.5,
|
||||
});
|
||||
let yPosition1 = 512;
|
||||
let yPosition2 = 498;
|
||||
let yPosition3 = 478;
|
||||
let yPosition4 = 458;
|
||||
let yPosition5 = 438;
|
||||
let yPosition6 = 418;
|
||||
let yPosition7 = 398;
|
||||
let yPosition8 = 363;
|
||||
let yPosition1 = ipY - 21;
|
||||
let yPosition2 = yPosition1 - 14;
|
||||
let yPosition3 = yPosition2 - 20;
|
||||
let yPosition4 = yPosition3 - 20;
|
||||
let yPosition5 = yPosition4 - 20;
|
||||
let yPosition6 = yPosition5 - 20;
|
||||
let yPosition7 = yPosition6 - 20;
|
||||
let yPosition8 = yPosition7 - 35;
|
||||
|
||||
auditTrail.slice(0, 3).forEach(async (x, i) => {
|
||||
const embedPng = x.Signature ? await pdfDoc.embedPng(x.Signature) : '';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import fs from 'node:fs';
|
||||
import { createHash } from 'node:crypto';
|
||||
import axios from 'axios';
|
||||
import { PDFDocument } from 'pdf-lib';
|
||||
import {
|
||||
@@ -28,6 +29,10 @@ const headers = {
|
||||
'X-Parse-Master-Key': masterKEY,
|
||||
};
|
||||
|
||||
function generateDocumentHash(buffer) {
|
||||
return createHash('sha256').update(buffer).digest('hex');
|
||||
}
|
||||
|
||||
async function unlinkFile(path) {
|
||||
if (fs.existsSync(path)) {
|
||||
try {
|
||||
@@ -44,11 +49,6 @@ async function uploadFile(pdfName, filepath) {
|
||||
const filedata = fs.readFileSync(filepath);
|
||||
let fileUrl;
|
||||
|
||||
// const file = new Parse.File(pdfName, [...filedata], 'application/pdf');
|
||||
// await file.save({ useMasterKey: true });
|
||||
// const fileRes = getSecureUrl(file.url());
|
||||
// fileUrl = fileRes.url;
|
||||
|
||||
const fileRes = await parseUploadFile(pdfName, filedata, 'application/pdf');
|
||||
fileUrl = getSecureUrl(fileRes?.url)?.url;
|
||||
|
||||
@@ -61,7 +61,7 @@ async function uploadFile(pdfName, filepath) {
|
||||
}
|
||||
|
||||
// `updateDoc` is used to update signedUrl, AuditTrail, Iscompleted in document
|
||||
async function updateDoc(docId, url, userId, ipAddress, data, className, sign) {
|
||||
async function updateDoc(docId, url, userId, ipAddress, data, className, sign, documentHash) {
|
||||
try {
|
||||
const UserPtr = { __type: 'Pointer', className: className, objectId: userId };
|
||||
const obj = {
|
||||
@@ -100,8 +100,16 @@ async function updateDoc(docId, url, userId, ipAddress, data, className, sign) {
|
||||
isCompleted = true;
|
||||
}
|
||||
const body = { SignedUrl: url, AuditTrail: updateAuditTrail, IsCompleted: isCompleted };
|
||||
if (documentHash && isCompleted) {
|
||||
body.DocumentHash = documentHash;
|
||||
}
|
||||
const signedRes = await axios.put(`${docUrl}/${docId}`, body, { headers });
|
||||
return { isCompleted: isCompleted, message: 'success', AuditTrail: updateAuditTrail };
|
||||
return {
|
||||
isCompleted: isCompleted,
|
||||
message: 'success',
|
||||
AuditTrail: updateAuditTrail,
|
||||
DocumentHash: documentHash && isCompleted ? documentHash : undefined,
|
||||
};
|
||||
} catch (err) {
|
||||
console.log('update doc err ', err);
|
||||
return 'err';
|
||||
@@ -183,8 +191,8 @@ async function sendCompletedMail(obj) {
|
||||
if (obj?.isCustomMail) {
|
||||
const tenant = sender?.TenantId;
|
||||
if (tenant) {
|
||||
subject = tenant?.CompletionSubject || '';
|
||||
body = tenant?.CompletionBody || '';
|
||||
subject = tenant?.CompletionSubject ? tenant?.CompletionSubject : subject;
|
||||
body = tenant?.CompletionBody ? tenant?.CompletionBody : body;
|
||||
} else {
|
||||
const userId = sender?.CreatedBy?.objectId || sender?.UserId?.objectId;
|
||||
if (userId) {
|
||||
@@ -198,8 +206,8 @@ async function sendCompletedMail(obj) {
|
||||
const tenantRes = await tenantQuery.first({ useMasterKey: true });
|
||||
if (tenantRes) {
|
||||
const _tenantRes = JSON.parse(JSON.stringify(tenantRes));
|
||||
subject = _tenantRes?.CompletionSubject || '';
|
||||
body = _tenantRes?.CompletionBody || '';
|
||||
subject = _tenantRes?.CompletionSubject ? tenant?.CompletionSubject : subject;
|
||||
body = _tenantRes?.CompletionBody ? tenant?.CompletionBody : body;
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('error in fetch tenant in signpdf', err.message);
|
||||
@@ -427,6 +435,7 @@ async function PDF(req) {
|
||||
let filePath = `./exports/${name}`;
|
||||
let signedFilePath = `./exports/signed_${name}`;
|
||||
let pdfSize = PdfBuffer.length;
|
||||
let documentHash;
|
||||
if (isCompleted) {
|
||||
const signersName = _resDoc.Signers?.map(x => x.Name + ' <' + x.Email + '>');
|
||||
const reason =
|
||||
@@ -444,6 +453,7 @@ async function PDF(req) {
|
||||
//`saveUrl` is used to save signed pdf in exports folder
|
||||
fs.writeFileSync(signedFilePath, signedDocs);
|
||||
pdfSize = signedDocs.length;
|
||||
documentHash = generateDocumentHash(signedDocs);
|
||||
console.log(`✅ PDF digitally signed created: ${signedFilePath} \n`);
|
||||
} else {
|
||||
//`saveUrl` is used to save signed pdf in exports folder
|
||||
@@ -464,12 +474,17 @@ async function PDF(req) {
|
||||
userIP, // client ipAddress,
|
||||
_resDoc, // auditTrail, signers, etc data
|
||||
className, // className based on flow
|
||||
sign // sign base64
|
||||
sign, // sign base64
|
||||
isCompleted ? documentHash : undefined
|
||||
);
|
||||
sendNotifyMail(_resDoc, signUser, mailProvider, publicUrl);
|
||||
saveFileUsage(pdfSize, data.imageUrl, _resDoc?.CreatedBy?.objectId);
|
||||
if (updatedDoc && updatedDoc.isCompleted) {
|
||||
const hashForDoc = documentHash || updatedDoc?.DocumentHash;
|
||||
const doc = { ..._resDoc, AuditTrail: updatedDoc.AuditTrail, SignedUrl: data.imageUrl };
|
||||
if (hashForDoc) {
|
||||
doc.DocumentHash = hashForDoc;
|
||||
}
|
||||
sendMailsaveCertifcate(doc, pfx, isCustomMail, mailProvider, `signed_${name}`);
|
||||
} else {
|
||||
unlinkFile(pfxname);
|
||||
|
||||
Reference in New Issue
Block a user