refactor(qpdf): move initialization logic to helpers module
Consolidate qpdf initialization code into helpers.ts to avoid duplication Improve error message for password protected PDFs Fortify encryption logic by auto-filling owner password when empty
This commit is contained in:
@@ -1,31 +1,6 @@
|
|||||||
import { showLoader, hideLoader, showAlert } from '../ui.js';
|
import { showLoader, hideLoader, showAlert } from '../ui.js';
|
||||||
import { downloadFile, readFileAsArrayBuffer } from '../utils/helpers.js';
|
import { downloadFile, initializeQpdf, readFileAsArrayBuffer } from '../utils/helpers.js';
|
||||||
import { state } from '../state.js';
|
import { state } from '../state.js';
|
||||||
import createModule from '@neslinesli93/qpdf-wasm';
|
|
||||||
|
|
||||||
let qpdfInstance: any = null;
|
|
||||||
|
|
||||||
async function initializeQpdf() {
|
|
||||||
if (qpdfInstance) {
|
|
||||||
return qpdfInstance;
|
|
||||||
}
|
|
||||||
showLoader('Initializing PDF engine...');
|
|
||||||
try {
|
|
||||||
qpdfInstance = await createModule({
|
|
||||||
locateFile: () => '/qpdf.wasm',
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to initialize qpdf-wasm:', error);
|
|
||||||
showAlert(
|
|
||||||
'Initialization Error',
|
|
||||||
'Could not load the PDF engine. Please refresh the page and try again.'
|
|
||||||
);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
hideLoader();
|
|
||||||
}
|
|
||||||
return qpdfInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function changePermissions() {
|
export async function changePermissions() {
|
||||||
const file = state.files[0];
|
const file = state.files[0];
|
||||||
@@ -156,7 +131,7 @@ export async function changePermissions() {
|
|||||||
} else {
|
} else {
|
||||||
showAlert(
|
showAlert(
|
||||||
'Processing Failed',
|
'Processing Failed',
|
||||||
`An error occurred: ${error.message || 'The PDF might be corrupted.'}`
|
`An error occurred: ${error.message || 'The PDF might be corrupted or password protected.'}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,31 +1,6 @@
|
|||||||
import { showLoader, hideLoader, showAlert } from '../ui.js';
|
import { showLoader, hideLoader, showAlert } from '../ui.js';
|
||||||
import { downloadFile, readFileAsArrayBuffer } from '../utils/helpers.js';
|
import { downloadFile, initializeQpdf, readFileAsArrayBuffer } from '../utils/helpers.js';
|
||||||
import { state } from '../state.js';
|
import { state } from '../state.js';
|
||||||
import createModule from '@neslinesli93/qpdf-wasm';
|
|
||||||
|
|
||||||
let qpdfInstance: any = null;
|
|
||||||
|
|
||||||
async function initializeQpdf() {
|
|
||||||
if (qpdfInstance) {
|
|
||||||
return qpdfInstance;
|
|
||||||
}
|
|
||||||
showLoader('Initializing decryption engine...');
|
|
||||||
try {
|
|
||||||
qpdfInstance = await createModule({
|
|
||||||
locateFile: () => '/qpdf.wasm',
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to initialize qpdf-wasm:', error);
|
|
||||||
showAlert(
|
|
||||||
'Initialization Error',
|
|
||||||
'Could not load the decryption engine. Please refresh the page and try again.'
|
|
||||||
);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
hideLoader();
|
|
||||||
}
|
|
||||||
return qpdfInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function decrypt() {
|
export async function decrypt() {
|
||||||
const file = state.files[0];
|
const file = state.files[0];
|
||||||
|
|||||||
@@ -1,38 +1,13 @@
|
|||||||
import { showLoader, hideLoader, showAlert } from '../ui.js';
|
import { showLoader, hideLoader, showAlert } from '../ui.js';
|
||||||
import { downloadFile, readFileAsArrayBuffer } from '../utils/helpers.js';
|
import { downloadFile, initializeQpdf, readFileAsArrayBuffer } from '../utils/helpers.js';
|
||||||
import { state } from '../state.js';
|
import { state } from '../state.js';
|
||||||
import createModule from '@neslinesli93/qpdf-wasm';
|
|
||||||
|
|
||||||
let qpdfInstance: any = null;
|
|
||||||
|
|
||||||
async function initializeQpdf() {
|
|
||||||
if (qpdfInstance) {
|
|
||||||
return qpdfInstance;
|
|
||||||
}
|
|
||||||
showLoader('Initializing encryption engine...');
|
|
||||||
try {
|
|
||||||
qpdfInstance = await createModule({
|
|
||||||
locateFile: () => '/qpdf.wasm',
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to initialize qpdf-wasm:', error);
|
|
||||||
showAlert(
|
|
||||||
'Initialization Error',
|
|
||||||
'Could not load the encryption engine. Please refresh the page and try again.'
|
|
||||||
);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
hideLoader();
|
|
||||||
}
|
|
||||||
return qpdfInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function encrypt() {
|
export async function encrypt() {
|
||||||
const file = state.files[0];
|
const file = state.files[0];
|
||||||
const userPassword =
|
const userPassword =
|
||||||
(document.getElementById('user-password-input') as HTMLInputElement)
|
(document.getElementById('user-password-input') as HTMLInputElement)
|
||||||
?.value || '';
|
?.value || '';
|
||||||
const ownerPassword =
|
const ownerPasswordInput =
|
||||||
(document.getElementById('owner-password-input') as HTMLInputElement)
|
(document.getElementById('owner-password-input') as HTMLInputElement)
|
||||||
?.value || '';
|
?.value || '';
|
||||||
|
|
||||||
@@ -41,6 +16,9 @@ export async function encrypt() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ownerPassword = ownerPasswordInput || userPassword;
|
||||||
|
const hasDistinctOwnerPassword = ownerPasswordInput !== '';
|
||||||
|
|
||||||
const inputPath = '/input.pdf';
|
const inputPath = '/input.pdf';
|
||||||
const outputPath = '/output.pdf';
|
const outputPath = '/output.pdf';
|
||||||
let qpdf: any;
|
let qpdf: any;
|
||||||
@@ -61,11 +39,12 @@ export async function encrypt() {
|
|||||||
inputPath,
|
inputPath,
|
||||||
'--encrypt',
|
'--encrypt',
|
||||||
userPassword,
|
userPassword,
|
||||||
ownerPassword, // Can be empty
|
ownerPassword,
|
||||||
'256',
|
'256',
|
||||||
];
|
];
|
||||||
|
|
||||||
if (ownerPassword) {
|
// Only add restrictions if a distinct owner password was provided
|
||||||
|
if (hasDistinctOwnerPassword) {
|
||||||
args.push(
|
args.push(
|
||||||
'--modify=none',
|
'--modify=none',
|
||||||
'--extract=n',
|
'--extract=n',
|
||||||
@@ -78,12 +57,10 @@ export async function encrypt() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ownerPassword) {
|
|
||||||
args.push('--allow-insecure');
|
|
||||||
}
|
|
||||||
|
|
||||||
args.push('--', outputPath);
|
args.push('--', outputPath);
|
||||||
|
|
||||||
|
console.log(args);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
qpdf.callMain(args);
|
qpdf.callMain(args);
|
||||||
} catch (qpdfError: any) {
|
} catch (qpdfError: any) {
|
||||||
@@ -106,9 +83,9 @@ export async function encrypt() {
|
|||||||
hideLoader();
|
hideLoader();
|
||||||
|
|
||||||
let successMessage = 'PDF encrypted successfully with 256-bit AES!';
|
let successMessage = 'PDF encrypted successfully with 256-bit AES!';
|
||||||
if (!ownerPassword) {
|
if (!hasDistinctOwnerPassword) {
|
||||||
successMessage +=
|
successMessage +=
|
||||||
' Note: Without an owner password, the PDF has no usage restrictions.';
|
' Note: Without a separate owner password, the PDF has no usage restrictions.';
|
||||||
}
|
}
|
||||||
|
|
||||||
showAlert('Success', successMessage);
|
showAlert('Success', successMessage);
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import createModule from '@neslinesli93/qpdf-wasm';
|
||||||
|
import { showLoader, hideLoader, showAlert } from '../ui';
|
||||||
|
|
||||||
const STANDARD_SIZES = {
|
const STANDARD_SIZES = {
|
||||||
A4: { width: 595.28, height: 841.89 },
|
A4: { width: 595.28, height: 841.89 },
|
||||||
Letter: { width: 612, height: 792 },
|
Letter: { width: 612, height: 792 },
|
||||||
@@ -146,3 +149,31 @@ export function formatIsoDate(isoDateString) {
|
|||||||
return isoDateString; // Return original string on any error
|
return isoDateString; // Return original string on any error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let qpdfInstance: any = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize qpdf-wasm singleton.
|
||||||
|
* Subsequent calls return the same instance.
|
||||||
|
*/
|
||||||
|
export async function initializeQpdf() {
|
||||||
|
if (qpdfInstance) return qpdfInstance;
|
||||||
|
|
||||||
|
showLoader('Initializing PDF engine...');
|
||||||
|
try {
|
||||||
|
qpdfInstance = await createModule({
|
||||||
|
locateFile: () => '/qpdf.wasm',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to initialize qpdf-wasm:', error);
|
||||||
|
showAlert(
|
||||||
|
'Initialization Error',
|
||||||
|
'Could not load the PDF engine. Please refresh the page and try again.'
|
||||||
|
);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
hideLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
return qpdfInstance;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user