Files
OpenSign/apps/OpenSignServer/cloud/parsefunction/generateCertificatebydocId.js
T
prafull-opensignlabs e299891174 v2.12.0
feat: create duplicate template functionality
feat: add support of csv and xlsx for bulk contacts import
feat: add info text for forms and dashboard button
feat: implement functionality to delete a PDF page while editing the document
feat: show completed documents in which signers included but not owner in completed reports
feat: add delete folder button in opensign drive
feat: introduce Bcc email support for sending completed documents
feat: allow merging multiple pdf while drafting document and template
feat: add 'My Initials' tab for auto-signing in request-sign flow
feat: add support for redirect URL to navigate after document completion
feat: introduce privacy policy and digital signature terms before signing documents.
feat: add feature to allow adding new pages to existing document
feat: add save signature, initials, stamp functionality in sign pad for logged in user
feat: add preferences menu
feat: add save custom email template, notifyonsignature, set timezone, allow signature types in preferences
feat: secure local url
feat: implement Italian language translation
feat: implement German language translation
feat: update menu name from report to documents and shift contactbook in main menu
feat: provide edit contact functionality

fix: unable to delete folder when all its documents are deleted
fix: fields.push is not function
fix: document loading issue in opensign drive
fix: adjust the guest signature flow to display the document in full screen, eliminating any blank space which is displayed below the place holder in mobile view
fix: resolve issue of instance of pdfdict or pdfstream but got undefined

build(deps): update dependencies

refactor: change note text from add contact form
2025-02-10 14:41:16 +00:00

110 lines
4.3 KiB
JavaScript

import { SignPdf } from '@signpdf/signpdf';
import { P12Signer } from '@signpdf/signer-p12';
import { pdflibAddPlaceholder } from '@signpdf/placeholder-pdf-lib';
import { PDFDocument } from 'pdf-lib';
import Parse from 'parse/node.js';
import fs from 'node:fs';
import dotenv from 'dotenv';
import GenerateCertificate from './pdf/GenerateCertificate.js';
import { getSecureUrl } from '../../Utils.js';
dotenv.config();
const eSignName = 'opensign';
const eSigncontact = 'hello@opensignlabs.com';
// `uploadFile` is used to create url in from pdfFile
async function uploadFile(
pdfName,
filepath,
) {
try {
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;
return { imageUrl: fileUrl };
} catch (err) {
console.log('Err ', err);
// `unlinkCertificate` is used to remove exported signed pdf file from exports folder
unlinkCertificate(filepath);
}
}
async function unlinkCertificate(path) {
if (fs.existsSync(path)) {
try {
fs.unlinkSync(path);
} catch (err) {
console.log('Err in unlink certificate generatecertificatebydocid', err);
}
}
}
export default async function generateCertificatebydocId(req) {
const docId = req.params.docId;
// const userId = req.headers.userid;
if (!docId) {
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'please provide parameter.');
}
// `P12Buffer` used to create buffer from p12 certificate
const pfxFile = process.env.PFX_BASE64;
// const P12Buffer = fs.readFileSync();
const P12Buffer = Buffer.from(pfxFile, 'base64');
const certificatePath = `./exports/certificate_${docId}.pdf`;
try {
const getDocument = new Parse.Query('contracts_Document');
getDocument.include('ExtUserPtr,Signers,AuditTrail.UserPtr,Placeholders,ExtUserPtr.TenantId');
const docRes = await getDocument.get(docId, { useMasterKey: true });
if (docRes && docRes?.get('IsCompleted') && !docRes?.get('CertificateUrl')) {
const _docRes = JSON.parse(JSON.stringify(docRes));
const filteredaudit = _docRes?.AuditTrail?.filter(x => x?.UserPtr?.objectId);
// Create a reversed copy of the array and find the last object with 'signedOn'
const lastObj = [...filteredaudit].reverse().find(obj => obj.hasOwnProperty('SignedOn'));
const completedAt = lastObj.SignedOn;
const doc = { ..._docRes, completedAt: completedAt };
const certificate = await GenerateCertificate(doc);
const certificatePdf = await PDFDocument.load(certificate);
const p12 = new P12Signer(P12Buffer, { passphrase: process.env.PASS_PHRASE || null });
// `pdflibAddPlaceholder` is used to add code of only digitial sign in certificate
pdflibAddPlaceholder({
pdfDoc: certificatePdf,
reason: 'Digitally signed by OpenSign.',
location: 'n/a',
name: eSignName,
contactInfo: eSigncontact,
signatureLength: 15000,
});
const pdfWithPlaceholderBytes = await certificatePdf.save();
const CertificateBuffer = Buffer.from(pdfWithPlaceholderBytes);
//`new signPDF` create new instance of CertificateBuffer and p12Buffer
const certificateOBJ = new SignPdf();
// `signedCertificate` is used to sign certificate digitally
const signedCertificate = await certificateOBJ.sign(CertificateBuffer, p12);
//below is used to save signed certificate in exports folder
fs.writeFileSync(certificatePath, signedCertificate);
const file = await uploadFile(
'certificate.pdf',
certificatePath,
);
const updateDoc = new Parse.Object('contracts_Document');
updateDoc.id = doc.objectId;
updateDoc.set('CertificateUrl', file.imageUrl);
const updateDocRes = await updateDoc.save(null, { useMasterKey: true });
unlinkCertificate(certificatePath);
return { CertificateUrl: file.imageUrl };
} else {
return { CertificateUrl: '' };
}
} catch (error) {
console.error('Error fetching or processing document:', error);
const code = error?.code || 400;
const message = error?.message || 'Something went wrong.';
unlinkCertificate(certificatePath);
throw new Parse.Error(code, message);
}
}