Revert "v2.39.0 (#2180)"

This reverts commit 1e228c86c3.
This commit is contained in:
Raktima
2026-05-25 17:24:36 +05:30
committed by GitHub
parent 1e228c86c3
commit 7b4d0bf052
92 changed files with 5372 additions and 8680 deletions
@@ -3,13 +3,6 @@ import fs from 'node:fs';
import fontkit from '@pdf-lib/fontkit';
import { formatDateTime } from '../../../Utils.js';
const formatDateStr = (dateStr, DateFormat, timezone, Is12Hr) => {
if (!dateStr) return '';
const date = new Date(dateStr);
if (isNaN(date.getTime())) return dateStr;
return formatDateTime(date, DateFormat, timezone, Is12Hr);
};
export default async function GenerateCertificate(docDetails) {
const timezone = docDetails?.ExtUserPtr?.Timezone || '';
const Is12Hr = docDetails?.ExtUserPtr?.Is12HourTime || false;
@@ -19,9 +12,7 @@ export default async function GenerateCertificate(docDetails) {
const fontBytes = fs.readFileSync('./font/times.ttf'); //
pdfDoc.registerFontkit(fontkit);
const timesRomanFont = await pdfDoc.embedFont(fontBytes, { subset: true });
const pngUrl = fs.readFileSync('./images/logo.png').buffer;
const naSignUrl = fs.readFileSync('./images/na_sign.png').buffer;
const nasign = await pdfDoc.embedPng(naSignUrl);
const pngUrl = fs.readFileSync('./logo.png').buffer;
const pngImage = await pdfDoc.embedPng(pngUrl);
const page = pdfDoc.addPage();
const { width, height } = page.getSize();
@@ -38,7 +29,7 @@ export default async function GenerateCertificate(docDetails) {
const textKeyColor = rgb(0.12, 0.12, 0.12);
const textValueColor = rgb(0.3, 0.3, 0.3);
const completedAt = docDetails?.completedAt ? new Date(docDetails?.completedAt) : new Date();
const completedAtperTimezone = formatDateStr(completedAt, DateFormat, timezone, Is12Hr);
const completedAtperTimezone = formatDateTime(completedAt, DateFormat, timezone, Is12Hr);
const completedUTCtime = completedAtperTimezone;
const signersCount = docDetails?.Signers?.length || 1;
const generateAt = docDetails?.completedAt ? new Date(docDetails?.completedAt) : new Date();
@@ -52,19 +43,9 @@ export default async function GenerateCertificate(docDetails) {
const company = docDetails?.ExtUserPtr?.Company || '';
const documentHash = docDetails?.DocumentHash || '';
const createdAt = docDetails?.DocSentAt?.iso || docDetails.createdAt;
const createdAtperTimezone = formatDateStr(createdAt, DateFormat, timezone, Is12Hr);
const createdAtperTimezone = formatDateTime(createdAt, DateFormat, timezone, Is12Hr);
const IsEnableOTP = docDetails?.IsEnableOTP || false;
const placeholders = Array.isArray(docDetails?.Placeholders) ? docDetails.Placeholders : [];
const filteredaudit = docDetails?.AuditTrail?.filter(x => {
if (!x?.UserPtr?.objectId) return false;
return true;
});
const toTs = v => {
if (!v) return 0;
if (typeof v === 'object' && v?.iso) return new Date(v.iso).getTime() || 0;
const t = new Date(v).getTime();
return Number.isFinite(t) ? t : 0;
};
const filteredaudit = docDetails?.AuditTrail?.filter(x => x?.UserPtr?.objectId);
const auditTrail =
docDetails?.Signers?.length > 0
? filteredaudit?.map(x => {
@@ -75,7 +56,6 @@ export default async function GenerateCertificate(docDetails) {
SignedOn: x?.SignedOn || generatedUTCTime,
ViewedOn: x?.ViewedOn || x?.SignedOn || generatedUTCTime,
Signature: x?.Signature || '',
_signedOnTs: toTs(x?.SignedOn),
};
})
: [
@@ -85,12 +65,8 @@ export default async function GenerateCertificate(docDetails) {
SignedOn: filteredaudit[0]?.SignedOn || generatedUTCTime,
ViewedOn: filteredaudit[0]?.ViewedOn || filteredaudit[0]?.SignedOn || generatedUTCTime,
Signature: filteredaudit[0]?.Signature || '',
_signedOnTs: toTs(filteredaudit[0]?.SignedOn),
},
];
if (Array.isArray(auditTrail)) {
auditTrail.sort((a, b) => (a?._signedOnTs || 0) - (b?._signedOnTs || 0));
}
const ownerName = docDetails?.SenderName || docDetails.ExtUserPtr?.Name || 'n/a';
const ownerEmail = docDetails?.SenderMail || docDetails.ExtUserPtr?.Email || 'n/a';
@@ -327,63 +303,24 @@ export default async function GenerateCertificate(docDetails) {
let yPosition7 = yPosition6 - 20;
let yPosition8 = yPosition7 - 35;
// A signer/approver block spans from yPosition1 down to yPosition8 (the
// separator line at the bottom of the block). The signature image's
// bottom edge sits at yPosition7 - 30 and must remain inside the page
// border (whose bottom edge is at startY). Use the lowest of those two
// values when deciding whether the next block fits on the current page.
const minY = startY + 5;
const blockBottom = () => Math.min(yPosition7 - 30, yPosition8);
// Helper that resets the y-positions to the top of a freshly added page so
// the next block starts cleanly under the border.
const startNewPage = () => {
const newPage = pdfDoc.addPage();
newPage.drawRectangle({
x: startX,
y: startY,
width: width - 2 * startX,
height: height - 2 * startY,
borderColor: borderColor,
borderWidth: 1,
});
yPosition1 = newPage.getHeight() - 40;
yPosition2 = yPosition1 - 20;
yPosition3 = yPosition2 - 20;
yPosition4 = yPosition3 - 20;
yPosition5 = yPosition4 - 20;
yPosition6 = yPosition5 - 20;
yPosition7 = yPosition6 - 20;
yPosition8 = yPosition7 - 35;
return newPage;
};
let currentPage = page;
for (let i = 0; i < auditTrail.length; i++) {
const x = auditTrail[i];
// If the next block would overflow the bottom border, move to a new page.
if (blockBottom() < minY) {
currentPage = startNewPage();
}
const embedPng = x.Signature ? await pdfDoc.embedPng(x.Signature) : nasign;
const headerLabel = `${i + 1}. ${'Signer'}`;
const signedOnLabel = 'Signed on :';
currentPage.drawText(headerLabel, {
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,
});
currentPage.drawText('Name :', {
page.drawText('Name :', {
x: 30,
y: yPosition2,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(x?.Name || '', {
page.drawText(x?.Name, {
x: 75,
y: yPosition2,
size: signertext,
@@ -392,14 +329,14 @@ export default async function GenerateCertificate(docDetails) {
});
if (IsEnableOTP) {
currentPage.drawText('Security level :', {
page.drawText('Security level :', {
x: half + 120,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText('Email, OTP Auth', {
page.drawText('Email, OTP Auth', {
x: half + 190,
y: yPosition2,
size: timeText,
@@ -408,14 +345,15 @@ export default async function GenerateCertificate(docDetails) {
});
}
currentPage.drawText('Email :', {
page.drawText('Email :', {
x: 30,
y: yPosition3,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(x?.Email || '', {
page.drawText(x?.Email, {
x: 75,
y: yPosition3,
size: signertext,
@@ -423,14 +361,15 @@ export default async function GenerateCertificate(docDetails) {
color: textValueColor,
});
currentPage.drawText('Viewed on :', {
page.drawText('Viewed on :', {
x: 30,
y: yPosition4,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(`${formatDateStr(x?.ViewedOn, DateFormat, timezone, Is12Hr)}`, {
page.drawText(`${formatDateTime(x.ViewedOn, DateFormat, timezone, Is12Hr)}`, {
x: 97,
y: yPosition4,
size: signertext,
@@ -438,30 +377,31 @@ export default async function GenerateCertificate(docDetails) {
color: textValueColor,
});
currentPage.drawText(signedOnLabel, {
page.drawText('Signed on :', {
x: 30,
y: yPosition5,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
const signedOnValueX = 30 + timesRomanFont.widthOfTextAtSize(signedOnLabel, signertext) + 5;
currentPage.drawText(`${formatDateStr(x?.SignedOn, DateFormat, timezone, Is12Hr)}`, {
x: signedOnValueX,
page.drawText(`${formatDateTime(x.SignedOn, DateFormat, timezone, Is12Hr)}`, {
x: 95,
y: yPosition5,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('IP address :', {
page.drawText('IP address :', {
x: 30,
y: yPosition6,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(x?.ipAddress || '', {
page.drawText(x?.ipAddress, {
x: 95,
y: yPosition6,
size: signertext,
@@ -469,14 +409,15 @@ export default async function GenerateCertificate(docDetails) {
color: textValueColor,
});
currentPage.drawText('Signature :', {
page.drawText('Signature :', {
x: 30,
y: yPosition7,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawRectangle({
page.drawRectangle({
x: 98,
y: yPosition7 - 30,
width: 104,
@@ -485,14 +426,14 @@ export default async function GenerateCertificate(docDetails) {
borderWidth: 1,
});
if (embedPng) {
currentPage.drawImage(embedPng, {
page.drawImage(embedPng, {
x: 100,
y: yPosition7 - 27,
width: 100,
height: 40,
});
}
currentPage.drawLine({
page.drawLine({
start: { x: 30, y: yPosition8 },
end: { x: width - 30, y: yPosition8 },
color: rgb(0.12, 0.12, 0.12),
@@ -507,6 +448,185 @@ export default async function GenerateCertificate(docDetails) {
yPosition6 = yPosition5 - 20;
yPosition7 = yPosition6 - 20;
yPosition8 = yPosition8 - 174;
});
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 = yPosition8;
// 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;
yPosition5 = yPosition4 - 20;
yPosition6 = yPosition5 - 20;
yPosition7 = yPosition6 - 20;
yPosition8 = currentPage.getHeight() - 190;
}
currentPage.drawText(`Signer ${4 + i}`, {
x: 30,
y: yPosition1,
size: subtitle,
font: timesRomanFont,
color: titleColor,
});
currentPage.drawText('Name :', {
x: 30,
y: yPosition2,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(x?.Name, {
x: 75,
y: yPosition2,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
if (IsEnableOTP) {
currentPage.drawText('Security level :', {
x: half + 120,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(`Email, OTP Auth`, {
x: half + 190,
y: yPosition2,
size: timeText,
font: timesRomanFont,
color: textValueColor,
});
}
currentPage.drawText('Email :', {
x: 30,
y: yPosition3,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(x?.Email, {
x: 75,
y: yPosition3,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('Viewed on :', {
x: 30,
y: yPosition4,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(`${formatDateTime(x.ViewedOn, DateFormat, timezone, Is12Hr)}`, {
x: 97,
y: yPosition4,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('Signed on :', {
x: 30,
y: yPosition5,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(`${formatDateTime(x.SignedOn, DateFormat, timezone, Is12Hr)}`, {
x: 95,
y: yPosition5,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('IP address :', {
x: 30,
y: yPosition6,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawText(x?.ipAddress, {
x: 100,
y: yPosition6,
size: signertext,
font: timesRomanFont,
color: textValueColor,
});
currentPage.drawText('Signature :', {
x: 30,
y: yPosition7,
size: signertext,
font: timesRomanFont,
color: textKeyColor,
});
currentPage.drawRectangle({
x: 98,
y: yPosition7 - 27,
width: 104,
height: 44,
borderColor: rgb(0.22, 0.18, 0.47),
borderWidth: 1,
});
if (embedPng) {
currentPage.drawImage(embedPng, {
x: 100,
y: yPosition7 - 25,
width: 100,
height: 40,
});
}
currentPage.drawLine({
start: { x: 30, y: yPosition8 },
end: { x: width - 30, y: yPosition8 },
color: rgb(0.12, 0.12, 0.12),
thickness: 0.5,
});
// Update y positions for the next entry
yPosition1 = yPosition8 - 20;
yPosition2 = yPosition1 - 20;
yPosition3 = yPosition2 - 20;
yPosition4 = yPosition3 - 20;
yPosition5 = yPosition4 - 20;
yPosition6 = yPosition5 - 20;
yPosition7 = yPosition6 - 20;
yPosition8 = yPosition8 - 174;
});
}
const pdfBytes = await pdfDoc.save();