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

132 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) {
const decryptedBlob = await response.blob();
this.removeErrorBanner();
return new File([decryptedBlob], file.name, {type: 'application/pdf'});
} 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 = '';
}
}