'Detect in browser if PDF is locked or encrypted
In my application, a user can upload a PDF which other users can later view. For my usecase, I need to ensure that the PDFs are not locked or encrypted and can be viewed by any other user.
To do this, I am asking users to upload unlocked PDFs and would like to throw an error if the PDF is locked, before I try to upload to S3.
I haven't found a consensus on what might be the best way to do this, in-browser? Do I try to read the buffer and throw an error if I am unable to? Or is there another performant and efficient way of detecting this?
Solution 1:[1]
It's better for the user experience, bandwidth, and performance to detect the status on the client side. You can have a file input element on your page, and trap the onChange event.
<input type="file" id="pdfFile" size="50" onChange='processFile' />
Inside of the onChange-handling function, you can get at the file bytes and load into a buffer. For code and more details, see reading file contents on the client side in javascript in various browsers.
You'll need to do some PDF parsing to learn the locked/encrypted status, but I imagine there are JS libraries that do it. Even if you have very large PDFs to parse, it will always be faster than uploading the PDF to the server, since that upload time will be a function of file size.
Cases I could see for uploading the file instead of client-side parsing:
- you are targeting lower-end mobile devices and expect PDFs that are +100mb.
- you will be running on browsers with Javascript restrictions
- you always want to upload the file to your server even if the PDF is protected, and you've worked out that the user experience is better
Solution 2:[2]
You can try using the below solution:
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function () {
var files = new Blob([reader.result], {type: 'application/pdf'});
files.text().then(x=> {
console.log("isEncrypted", x.includes("Encrypt")) // true, if Encrypted
console.log("isEncrypted", x.substring(x.lastIndexOf("<<"), x.lastIndexOf(">>")).includes("/Encrypt"));
console.log(file.name);
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Abhineet Kandele |
