mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2024-12-31 00:08:08 +01:00
PDF decryption
This commit is contained in:
parent
dcafc0d487
commit
4d017610b8
90
src/main/resources/static/js/multitool/DecryptFiles.js
Normal file
90
src/main/resources/static/js/multitool/DecryptFiles.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
export class DecryptFile {
|
||||||
|
async decryptFile(file) {
|
||||||
|
try {
|
||||||
|
const password = prompt('This file is password-protected. Please enter the password:');
|
||||||
|
|
||||||
|
if (password === null) {
|
||||||
|
// User cancelled
|
||||||
|
console.error(`Password prompt cancelled for PDF: ${file.name}`);
|
||||||
|
this.showErrorBanner(`Operation cancelled for PDF: ${file.name}`, 'You cancelled the decryption process.');
|
||||||
|
return null; // No file to return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password) {
|
||||||
|
// No password provided
|
||||||
|
console.error(`No password provided for encrypted PDF: ${file.name}`);
|
||||||
|
this.showErrorBanner(`No password provided for encrypted PDF: ${file.name}`, 'Please enter a valid password.');
|
||||||
|
return null; // No file to return
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('fileInput', file);
|
||||||
|
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(`Server error while decrypting: ${errorText}`);
|
||||||
|
this.showErrorBanner(
|
||||||
|
'Please try again with the correct password.',
|
||||||
|
errorText,
|
||||||
|
`Incorrect password for PDF: ${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(
|
||||||
|
`Decryption error for PDF: ${file.name}`,
|
||||||
|
error.message || 'Unexpected error occurred.',
|
||||||
|
'There was an error processing the file. Please try again.'
|
||||||
|
);
|
||||||
|
return null; // No file to return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkFileEncrypted(file) {
|
||||||
|
try {
|
||||||
|
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||||
|
const arrayBuffer = await file.arrayBuffer(); // Convert file to ArrayBuffer
|
||||||
|
await pdfjsLib.getDocument({
|
||||||
|
data: arrayBuffer,
|
||||||
|
password: '',
|
||||||
|
}).promise;
|
||||||
|
|
||||||
|
return false; // File is not encrypted
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === 'PasswordException') {
|
||||||
|
return true; // File is encrypted
|
||||||
|
}
|
||||||
|
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 = '';
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import {SplitAllCommand} from './commands/split.js';
|
|||||||
import {UndoManager} from './UndoManager.js';
|
import {UndoManager} from './UndoManager.js';
|
||||||
import {PageBreakCommand} from './commands/page-break.js';
|
import {PageBreakCommand} from './commands/page-break.js';
|
||||||
import {AddFilesCommand} from './commands/add-page.js';
|
import {AddFilesCommand} from './commands/add-page.js';
|
||||||
|
import {DecryptFile} from './DecryptFiles.js';
|
||||||
|
|
||||||
class PdfContainer {
|
class PdfContainer {
|
||||||
fileName;
|
fileName;
|
||||||
@ -40,6 +41,8 @@ class PdfContainer {
|
|||||||
this.removeAllElements = this.removeAllElements.bind(this);
|
this.removeAllElements = this.removeAllElements.bind(this);
|
||||||
this.resetPages = this.resetPages.bind(this);
|
this.resetPages = this.resetPages.bind(this);
|
||||||
|
|
||||||
|
this.decryptFile = new DecryptFile();
|
||||||
|
|
||||||
this.undoManager = undoManager || new UndoManager();
|
this.undoManager = undoManager || new UndoManager();
|
||||||
|
|
||||||
this.pdfAdapters = pdfAdapters;
|
this.pdfAdapters = pdfAdapters;
|
||||||
@ -165,7 +168,6 @@ class PdfContainer {
|
|||||||
input.click();
|
input.click();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async addFilesFromFiles(files, nextSiblingElement, pages) {
|
async addFilesFromFiles(files, nextSiblingElement, pages) {
|
||||||
this.fileName = files[0].name;
|
this.fileName = files[0].name;
|
||||||
for (var i = 0; i < files.length; i++) {
|
for (var i = 0; i < files.length; i++) {
|
||||||
@ -173,17 +175,27 @@ class PdfContainer {
|
|||||||
let processingTime,
|
let processingTime,
|
||||||
errorMessage = null,
|
errorMessage = null,
|
||||||
pageCount = 0;
|
pageCount = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const file = files[i];
|
let decryptedFile = files[i];
|
||||||
if (file.type === 'application/pdf') {
|
|
||||||
const {renderer, pdfDocument} = await this.loadFile(file);
|
if (decryptedFile.type === 'application/pdf' && (await this.decryptFile.checkFileEncrypted(decryptedFile))) {
|
||||||
|
decryptedFile = await this.decryptFile.decryptFile(decryptedFile);
|
||||||
|
if (!decryptedFile) {
|
||||||
|
throw new Error('File decryption failed.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decryptedFile.type === 'application/pdf') {
|
||||||
|
const {renderer, pdfDocument} = await this.loadFile(decryptedFile);
|
||||||
pageCount = renderer.pageCount || 0;
|
pageCount = renderer.pageCount || 0;
|
||||||
pages = await this.addPdfFile(renderer, pdfDocument, nextSiblingElement, pages);
|
pages = await this.addPdfFile(renderer, pdfDocument, nextSiblingElement, pages);
|
||||||
} else if (file.type.startsWith('image/')) {
|
} else if (decryptedFile.type.startsWith('image/')) {
|
||||||
pages = await this.addImageFile(file, nextSiblingElement, pages);
|
pages = await this.addImageFile(decryptedFile, nextSiblingElement, pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
processingTime = Date.now() - startTime;
|
processingTime = Date.now() - startTime;
|
||||||
this.captureFileProcessingEvent(true, file, processingTime, null, pageCount);
|
this.captureFileProcessingEvent(true, decryptedFile, processingTime, null, pageCount);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
processingTime = Date.now() - startTime;
|
processingTime = Date.now() - startTime;
|
||||||
errorMessage = error.message || 'Unknown error';
|
errorMessage = error.message || 'Unknown error';
|
||||||
@ -194,6 +206,7 @@ class PdfContainer {
|
|||||||
document.querySelectorAll('.enable-on-file').forEach((element) => {
|
document.querySelectorAll('.enable-on-file').forEach((element) => {
|
||||||
element.disabled = false;
|
element.disabled = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
return pages;
|
return pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user