Skip to content

Instantly share code, notes, and snippets.

@Avi-E-Koenig
Created December 15, 2024 19:57
Show Gist options
  • Save Avi-E-Koenig/c34768a48fa17dbbec2e25c634e8e1d0 to your computer and use it in GitHub Desktop.
Save Avi-E-Koenig/c34768a48fa17dbbec2e25c634e8e1d0 to your computer and use it in GitHub Desktop.
import puppeteer from 'puppeteer';
import sharp from 'sharp';
import logger from '../../services/logger.js';
import PDFDocument from 'pdfkit';
import { promisify } from 'util';
import fs from 'fs';
import { Recipe } from 'muhammara';
export async function convertToPdf(url, pdfOptions = {}) {
const browser = await puppeteer.launch();
let page;
try {
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('PDF conversion timeout')), GLOBAL_TIMEOUT);
});
const conversionPromise = (async () => {
// Step 1: Use Puppeteer to generate a PDF
page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle2' });
const tempPdfPath = './tempPdfFile.pdf';
await page.pdf({
path: tempPdfPath, // Save the PDF directly to a file
format: 'A4',
printBackground: true
});
// Wait for Puppeteer to finish generating the PDF
await new Promise((resolve, reject) => {
fs.access(tempPdfPath, fs.constants.F_OK, (err) => {
if (err) {
reject(new Error('Failed to generate PDF with Puppeteer.'));
} else {
resolve();
}
});
});
// Step 2: Encrypt the PDF using Muhammara
const securedPdfPath = './securedPdfFile.pdf';
const pdfDoc = new Recipe(tempPdfPath, securedPdfPath);
pdfDoc
.encrypt({
userPassword: pdfOptions.userPassword || 'user_password_here',
ownerPassword: pdfOptions.ownerPassword || 'owner_password_here',
userProtectionFlag: 4 | 8 // Prevent copying and printing
})
.endPDF();
// Wait for the secured PDF to be written
await new Promise((resolve, reject) => {
fs.access(securedPdfPath, fs.constants.F_OK, (err) => {
if (err) {
reject(new Error('Failed to generate secured PDF with Muhammara.'));
} else {
resolve();
}
});
});
// Optionally delete the temporary PDF
try {
retryUnlink(tempPdfPath);
sleep(10000).then(() => retryUnlink(securedPdfPath));
} catch (error) {
console.error('Error while deleting the temp PDF file:', error);
}
return securedPdfPath; // Return path of the secured PDF
})();
return await Promise.race([timeoutPromise, conversionPromise]);
} catch (error) {
console.error('Error in convertToPdf:', { error: error.message, url });
throw error;
} finally {
if (page) await page.close();
await browser.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment