Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

134 lines
4.7 KiB
JavaScript
Raw Normal View History

2024-12-06 19:08:18 +00:00
export class DecryptFile {
async decryptFile(file, requiresPassword) {
2024-12-06 19:08:18 +00:00
try {
2024-12-12 13:07:50 +00:00
async function getCsrfToken() {
const cookieValue = document.cookie
.split('; ')
.find((row) => row.startsWith('XSRF-TOKEN='))
?.split('=')[1];
if (cookieValue) {
return cookieValue;
}
const csrfElement = document.querySelector('input[name="_csrf"]');
return csrfElement ? csrfElement.value : null;
}
const csrfToken = await getCsrfToken();
2024-12-06 19:08:18 +00:00
const formData = new FormData();
formData.append('fileInput', file);
if (requiresPassword) {
2024-12-10 16:39:06 +00:00
const password = prompt(`${window.decrypt.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(
2024-12-10 16:39:06 +00:00
`${window.decrypt.noPassword.replace('{0}', file.name)}`,
'',
2024-12-10 16:39:06 +00:00
`${window.decrypt.unexpectedError}`
);
return null; // No file to return
}
2024-12-06 19:08:18 +00:00
formData.append('password', password);
}
2024-12-06 19:08:18 +00:00
// Send decryption request
const response = await fetch('/api/v1/security/remove-password', {
method: 'POST',
body: formData,
2024-12-12 13:07:50 +00:00
headers: csrfToken ? {'X-XSRF-TOKEN': csrfToken} : undefined,
2024-12-06 19:08:18 +00:00
});
if (response.ok) {
this.removeErrorBanner();
Fix error banner not getting removed on correct upload (#3114) This line: https://github.com/Stirling-Tools/Stirling-PDF/blob/9a0dad8bd7f2ae4333dab78d6313c5d95c4ac9b8/src/main/resources/static/js/DecryptFiles.js#L50 Appears to not relinquish flow control correctly and leads to `this.removeErrorBanner()` not getting called. Since the program still functions correctly I simply ensured that `removeErrorBanner()` is called before the `await` call to ensure that it works. Uploading a functioning pdf will now successfully remove the error banner. As to why the await call isn't functioning correctly I'm not sure, but the download appears to be working as it only seems to skip the error banner part. Closes #2419 --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [x] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings ### Documentation - [x] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [x] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [x] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [x] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details.
2025-03-05 11:43:26 +01:00
const decryptedBlob = await response.blob();
return new File([decryptedBlob], file.name, {
type: "application/pdf",
});
2024-12-06 19:08:18 +00:00
} else {
const errorText = await response.text();
2024-12-10 16:39:06 +00:00
console.error(`${window.decrypt.invalidPassword} ${errorText}`);
2024-12-06 19:08:18 +00:00
this.showErrorBanner(
2024-12-10 16:39:06 +00:00
`${window.decrypt.invalidPassword}`,
2024-12-06 19:08:18 +00:00
errorText,
2024-12-10 16:39:06 +00:00
`${window.decrypt.invalidPasswordHeader.replace('{0}', file.name)}`
2024-12-06 19:08:18 +00:00
);
return null; // No file to return
}
} catch (error) {
// Handle network or unexpected errors
console.error(`Failed to decrypt PDF: ${file.name}`, error);
this.showErrorBanner(
2024-12-10 16:39:06 +00:00
`${window.decrypt.unexpectedError.replace('{0}', file.name)}`,
`${error.message || window.decrypt.unexpectedError}`,
2024-12-06 20:46:04 +00:00
error
2024-12-06 19:08:18 +00:00
);
return null; // No file to return
}
}
async checkFileEncrypted(file) {
try {
2024-12-10 16:39:06 +00:00
if (file.type !== 'application/pdf') {
return {isEncrypted: false, requiresPassword: false};
}
2024-12-06 19:08:18 +00:00
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
const arrayBuffer = await file.arrayBuffer();
const arrayBufferForPdfLib = arrayBuffer.slice(0);
const loadingTask = pdfjsLib.getDocument({
2024-12-06 19:08:18 +00:00
data: arrayBuffer,
});
await loadingTask.promise;
2024-12-06 19:08:18 +00:00
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.');
}
2024-12-06 19:08:18 +00:00
} 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};
}
2024-12-06 19:08:18 +00:00
}
2024-12-06 19:08:18 +00:00
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 = '';
}
}