export class DecryptFile { async decryptFile(file, requiresPassword) { try { const formData = new FormData(); formData.append('fileInput', file); if (requiresPassword) { const password = prompt(`${window.translations.passwordPrompt}`); if (password === null) { // User cancelled console.error(`Password prompt cancelled for PDF: ${file.name}`); return null; // No file to return } if (!password) { // No password provided console.error(`No password provided for encrypted PDF: ${file.name}`); this.showErrorBanner( `${window.translations.noPassword.replace('{0}', file.name)}`, '', `${window.translations.unexpectedError}` ); return null; // No file to return } formData.append('password', password); } // Send decryption request const response = await fetch('/api/v1/security/remove-password', { method: 'POST', body: formData, }); if (response.ok) { const decryptedBlob = await response.blob(); this.removeErrorBanner(); return new File([decryptedBlob], file.name, {type: 'application/pdf'}); } else { const errorText = await response.text(); console.error(`${window.translations.invalidPassword} ${errorText}`); this.showErrorBanner( `${window.translations.invalidPassword}`, errorText, `${window.translations.invalidPasswordHeader.replace('{0}', file.name)}` ); return null; // No file to return } } catch (error) { // Handle network or unexpected errors console.error(`Failed to decrypt PDF: ${file.name}`, error); this.showErrorBanner( `${window.translations.unexpectedError.replace('{0}', file.name)}`, `${error.message || window.translations.unexpectedError}`, error ); return null; // No file to return } } async checkFileEncrypted(file) { try { pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs'; const arrayBuffer = await file.arrayBuffer(); const arrayBufferForPdfLib = arrayBuffer.slice(0); const loadingTask = pdfjsLib.getDocument({ data: arrayBuffer, }); await loadingTask.promise; try { //Uses PDFLib.PDFDocument to check if unpassworded but encrypted const pdfDoc = await PDFLib.PDFDocument.load(arrayBufferForPdfLib); return {isEncrypted: false, requiresPassword: false}; } catch (error) { if (error.message.includes('Input document to `PDFDocument.load` is encrypted')) { return {isEncrypted: true, requiresPassword: false}; } console.error('Error checking encryption:', error); throw new Error('Failed to determine if the file is encrypted.'); } } catch (error) { if (error.name === 'PasswordException') { if (error.code === pdfjsLib.PasswordResponses.NEED_PASSWORD) { return {isEncrypted: true, requiresPassword: true}; } else if (error.code === pdfjsLib.PasswordResponses.INCORRECT_PASSWORD) { return {isEncrypted: true, requiresPassword: false}; } } console.error('Error checking encryption:', error); throw new Error('Failed to determine if the file is encrypted.'); } } showErrorBanner(message, stackTrace, error) { const errorContainer = document.getElementById('errorContainer'); errorContainer.style.display = 'block'; // Display the banner errorContainer.querySelector('.alert-heading').textContent = error; errorContainer.querySelector('p').textContent = message; document.querySelector('#traceContent').textContent = stackTrace; } removeErrorBanner() { const errorContainer = document.getElementById('errorContainer'); errorContainer.style.display = 'none'; // Hide the banner errorContainer.querySelector('.alert-heading').textContent = ''; errorContainer.querySelector('p').textContent = ''; document.querySelector('#traceContent').textContent = ''; } }