Merge pull request #861 from nxglabs/staging

fix: handle password protected pdf
This commit is contained in:
nxglabs
2025-06-18 14:03:05 +00:00
parent b0e0b38e8f
commit cbca22c308
81 changed files with 4906 additions and 2305 deletions
@@ -15,8 +15,6 @@ async function deductcount(docsCount, extUserId) {
async function sendMail(document, publicUrl) {
//sessionToken
const baseUrl = new URL(publicUrl);
// console.log("pdfDetails", pdfDetails);
const timeToCompleteDays = document?.TimeToCompleteDays || 15;
const ExpireDate = new Date(document.createdAt);
ExpireDate.setDate(ExpireDate.getDate() + timeToCompleteDays);
@@ -168,9 +166,9 @@ async function batchQuery(userId, Documents, Ip, parseConfig, type, publicUrl) {
})),
ACL: Acl,
SentToOthers: true,
RemindOnceInEvery: x.RemindOnceInEvery || 5,
RemindOnceInEvery: x.RemindOnceInEvery ? parseInt(x.RemindOnceInEvery) : 5,
AutomaticReminders: x.AutomaticReminders || false,
TimeToCompleteDays: x.TimeToCompleteDays || 15,
TimeToCompleteDays: x.TimeToCompleteDays ? parseInt(x.TimeToCompleteDays) : 15,
OriginIp: Ip,
DocSentAt: { __type: 'Date', iso: isoDate },
IsEnableOTP: x?.IsEnableOTP || false,
@@ -231,6 +229,7 @@ export default async function createBatchDocs(request) {
const sessionToken = request.headers?.sessiontoken;
const type = request.headers?.type || 'quicksend';
const Documents = JSON.parse(strDocuments);
const Ip = request?.headers?.['x-real-ip'] || '';
// Access the host from the headers
const publicUrl = request.headers.public_url;
@@ -65,7 +65,7 @@ export default async function generateCertificatebydocId(req) {
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` is used to add code of only digital sign in certificate
pdflibAddPlaceholder({
pdfDoc: certificatePdf,
reason: `Digitally signed by ${eSignName}.`,
@@ -2,19 +2,26 @@ import { cloudServerUrl } from '../../Utils.js';
import reportJson from './reportsJson.js';
import axios from 'axios';
// Escape regex special characters. Copied from filterDocs.js
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
export default async function getReport(request) {
const reportId = request.params.reportId;
const limit = request.params.limit;
const skip = request.params.skip;
const searchTerm = request.params.searchTerm || '';
const serverUrl = cloudServerUrl; //process.env.SERVER_URL;
const appId = process.env.APP_ID;
const masterKey = process.env.MASTER_KEY;
const sessionToken = request.headers['sessiontoken'] || request.headers['x-parse-session-token'];
try {
const userRes = await axios.get(serverUrl + '/users/me', {
headers: {
'X-Parse-Application-Id': appId,
'X-Parse-Session-Token': request.headers['sessiontoken'],
'X-Parse-Session-Token': sessionToken,
},
});
const userId = userRes.data && userRes.data.objectId;
@@ -25,7 +32,7 @@ export default async function getReport(request) {
const { params, keys } = json;
const orderBy = '-updatedAt';
const strKeys = keys.join();
let strParams = JSON.stringify(params);
let paramsObj = { ...params };
if (reportId == '6TeaPr321t') {
const extUserQuery = new Parse.Query('contracts_Users');
extUserQuery.equalTo('Email', userRes.data.email);
@@ -36,8 +43,8 @@ export default async function getReport(request) {
if (_extUser?.TeamIds && _extUser.TeamIds?.length > 0) {
let teamArr = [];
_extUser?.TeamIds?.forEach(x => (teamArr = [...teamArr, ...x.Ancestors]));
strParams = JSON.stringify({
...params,
paramsObj = {
...paramsObj,
$or: [
{ SharedWith: { $in: teamArr } },
{
@@ -55,15 +62,23 @@ export default async function getReport(request) {
},
},
],
});
};
} else {
strParams = JSON.stringify({
...params,
paramsObj = {
...paramsObj,
CreatedBy: { __type: 'Pointer', className: '_User', objectId: userId },
});
};
}
}
}
if (searchTerm) {
const escaped = escapeRegExp(searchTerm);
paramsObj = {
...paramsObj,
Name: { $regex: `.*${escaped}.*`, $options: 'i' },
};
}
const strParams = JSON.stringify(paramsObj);
const headers = {
'Content-Type': 'application/json',
'X-Parse-Application-Id': appId,
@@ -14,11 +14,14 @@ export default async function recreateDocument(request) {
if (!doc) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Document not found');
}
if (doc?.get('IsSignyourself')) {
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Signyourself Document not allowed');
}
const _docRes = doc?.toJSON();
const { objectId, SignedUrl, AuditTrail, ACL, DeclineBy, DeclineReason, ...docRes } = _docRes;
const createDoc = new Parse.Object('contracts_Document');
Object.entries(docRes).forEach(([key, value]) => {
if (key === 'IsDeclined') {
if (key === 'IsDeclined' || key === 'IsCompleted') {
createDoc.set(key, false);
} else {
createDoc.set(key, value);
@@ -55,7 +55,7 @@ export default function reportJson(id, userId) {
'ExpiryDate',
],
};
// In progess report
// In progress report
case '1MwEuxLEkF':
return {
reportName: 'In-progress documents',
@@ -123,6 +123,8 @@ export default function reportJson(id, userId) {
'TimeToCompleteDays',
'IsSignyourself',
'IsCompleted',
'ExpiryDate',
'IsSignyourself',
],
};
// declined documents report
@@ -51,6 +51,17 @@ export default async function saveAsTemplate(request) {
if (_docRes?.Placeholders?.length > 0) {
if (_docRes?.IsSignyourself) {
//add required option for all widget when save as template using signyour-self draft document
const updatedPlaceholder = _docRes?.Placeholders.map(pageItem => ({
...pageItem,
pos: pageItem.pos.map(p => ({
...p,
options: {
...p.options,
status: 'required',
},
})),
}));
const placeHolders = {
signerObjId: '',
signerPtr: {},
@@ -58,7 +69,7 @@ export default async function saveAsTemplate(request) {
blockColor: '#93a3db',
Role: 'Role 1',
email: '',
placeHolder: _docRes?.Placeholders,
placeHolder: updatedPlaceholder,
};
templateCls.set('Placeholders', [placeHolders]);
} else {
@@ -53,10 +53,16 @@ const makeEmail = async (
const isSecure =
new URL(url)?.protocol === 'https:' && new URL(url)?.hostname !== 'localhost';
if (isSecure) {
https.get(url, async function (response) {
response.pipe(Pdf);
response.on('end', () => resolve('success'));
});
https
.get(url, async function (response) {
response.pipe(Pdf);
Pdf.on('finish', () => resolve('success'));
Pdf.on('error', () => resolve('error'));
})
.on('error', e => {
console.error(`error: ${e.message}`);
resolve('error');
});
} else {
const httpsAgent = new https.Agent({ rejectUnauthorized: false }); // Disable SSL validation
axios