PDFs are extensively utilized in business settings, making their security a crucial aspect of numerous workflows. When developing a web application that involves opening PDFs, it’s likely that you will encounter password-protected documents. However, implementing this functionality from scratch can be time-consuming and incur significant maintenance costs, which might not align with your team’s current roadmap.
With Foxit’s
HTML provides convenient built-in file upload features that enable users to interact with files from their local machines within the browser. However, displaying PDFs using JavaScript can be a bit more intricate, particularly when dealing with password protection. In this comprehensive tutorial, you will construct a web application comprising a PDF upload form and an optional password field. When a password-protected PDF is uploaded, and the correct password is entered, users will be able to preview the file seamlessly. On the other hand, if an incorrect password is provided, an error message will be displayed, prompting users to retry.
To develop this application, you will utilize the
The Express generator makes it easy to set up a new application. Simply run the following command in your terminal:
npx express-generator --git --view=hbs
This command will create a new application with a .gitignore
file and Handlebars template files.
Add the dotenv npm package ( use to access your Foxit license key and serial number) and install Express’ dependencies:
npm i dotenv && npm i
After you’ve downloaded Foxit PDF SDK for Web, you will find your license key and serial number in theexamples/license-key.js
file. Next, create a new file at the root directory of your web application called .env
and add the two values:
LICENSE_SN=""
LICENSE_KEY=""
Copy the Foxit library into your web application so you can access it from the front end. Next, copy the lib/
directory from Foxit PDF SDK you downloaded and paste it into your web application’s public/
directory. Now the Foxit JavaScript PDF library will be available within your web application.
Lastly, you don’t want sensitive info or proprietary packages to end up in version control, so add the below to your .gitignore
file:
...
public/lib/
.env
Once your web application has all the necessary dependencies in place, you can proceed to create the route responsible for displaying the PDF preview using Foxit.
Every page in an Express application has a route, including the PDF upload page you’ll create in this demo. Update the routes/index.js
file to pass the license key and serial number to the view:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', {
licenseSN: process.env.LICENSE_SN,
licenseKey: process.env.LICENSE_KEY,
});
});
module.exports = router;
Allowing you to easily update your credentials on the server, without needing hard-code credentials that require a code change. By adding an authentication layer to your Express application, you can control access to the Foxit credentials and restrict visibility to authorized users.
Before the process.env
variables are available, you need to include the dotenv
library which loads variables from your .env
file. Open app.js
and add the following to the top of the file:
require('dotenv').config();
...
YourLICENSE_SN
and LICENSE_KEY
are being securely stored and passed to the front end only when required. Next, you will address the display portion of the web application.
Foxit’s PDF SDK will handle the majority of the work involved in checking the password and displaying the PDF to the user, but you need to administer the user interface for both file and password inputs. Prior to this, you need to update the layout so it includes base styles and then you can scale the ‘viewport`. This will result in a PDF preview which is correctly sized to the user’s display.
Open the views/layout.hbs
file and replace it with the following:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Foxit PDF Previewer</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/build/pure-min.css" integrity="sha384-cg6SkqEOCV1NbJoCu11+bm0NvBRc8IYLRGXkmNrqUBfTjmMYwNKPWBTIKyw9mHNJ" crossorigin="anonymous">
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<div class="container">
{{{body}}}
</div>
</body>
</html>
This will load thePureCSS styling library, but you can use any other front end styling framework you’re familiar with.
Open the views/index.hbs
file and replace it with the below:
<h1>PDF Previewer</h1>
<p>Use the form below to preview any password-protected PDF file in this web application.</p>
<!-- PDF Upload form -->
<form class="pure-form">
<fieldset>
<input type="password" id="password" placeholder="Enter PDF Password" />
<input class="original-pdf-upload-button" type="file" name="file" id="file" accept=".pdf,.fdf,.xfdf" multiple="multiple" />
<label class="pure-button new-pdf-upload-button" for="file">Select a PDF file</label>
</fieldset>
</form>
<!-- PDF Display Div -->
<div id="pdf-viewer"></div>
<!-- Foxit and custom JavaScript -->
<script src="/lib/PDFViewCtrl.full.js"></script>
<script>
var PDFViewer = PDFViewCtrl.PDFViewer;
var pdfViewer = new PDFViewer({
libPath: '/lib',
jr: {
licenseSN: "{{ licenseSN }}",
licenseKey: "{{ licenseKey }}",
},
});
pdfViewer.init('#pdf-viewer');
document.getElementById('file').onchange = function (e) {
if (!this.value) {
return;
}
var pdf,fdf;
for (var i = e.target.files.length; i--;) {
var file = e.target.files[i];
var filename = file.name;
if (/\.pdf$/i.test(filename)) {
pdf = file
} else if (/\.(x)?fdf$/i.test(filename)) {
fdf = file
}
}
var options = {password: '', fdf: {file: fdf}};
if (document.getElementById('password').value) {
options.password = document.getElementById('password').value;
document.getElementById('password').value = '';
}
pdfViewer.openPDFByFile(pdf, options);
this.value = '';
};
</script>
This file serves three purposes. First, it includes a PDF upload form with a password field. The file upload input element has a<label>
, this acts as a nicely styled upload button. Next, the <div id=”pdf-viewer”>
tag wraps the Foxit PDF reader which is used in the pdfViewer.init
function in the custom JavaScript. The last section of this file loads Foxit’s PDFViewCtrl.PDFViewer
class and initializes it using the code inside the <script>
tags.
The application’s functionality is nearly complete, but before you test, open up public/stylesheets/style.css
file and replace with the following:
body {
background-color: #f7f7f7;
color: #333333;
}
.container {
background-color: #ffffff;
margin: 0 auto;
padding: 30px;
}
/* File upload button styling */
.original-pdf-upload-button {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.new-pdf-upload-button {
top: -2px;
position: relative;
}
Allowing you to style the PDF upload button so it has a consistent look with the other PureCSS buttons, and also adds a bit of padding to your application.
To test your application, first save your work and then run npm start
from your terminal. Node will spin up a server, and your web app will be available at localhost:3000
.
To handle the scenario where a user enters an incorrect password while uploading a password-protected PDF file, you can enhance the existing code to display an error message and allow the user to try again. Here’s how you can implement this functionality:
Foxit’s pdfViewer.openPDFByFile
method returns a promise, if you would like to know when it resolves, add a callback to the then
or catch
methods.
Within your views/index.hbs
file, replace the pdfViewer.openPDFByFile…
line with the below:
...
pdfViewer.openPDFByFile(pdf, options)
.catch(error => {
console.error(error);
document.getElementById('wrong-password').style.display = 'block';
});
...
Add a new paragraph element at the top of the file called id=”wrong-password”
:
<p id="wrong-password" class="error"><strong>Whoops!</strong>
It looks like the password you entered was incorrect.
Please enter a password and try uploading your file again.
</p>
...
Lastly, you’ll need to add some styling so the error message is only shown then the catch
method is called. Within your public/stylesheets/style.css
file, add the below:
...
#wrong-password {
display: none;
}
.error {
background-color: #f5c0c0;
color: #792525;
padding: 10px;
}
If you enter an incorrect password (or leave the password field blank) and a password-protected PDF has been uploaded, you will see an error message, as you can see below:
In this tutorial, you have learned how to build a secure Node web application that enables users to preview password-protected PDFs in their browser. By leveraging Foxit PDF SDK, you can significantly reduce development time and effort. Foxit PDF SDK offers extensive
It’s worth noting that Foxit provides PDF SDKs not only for web applications but also for
Also published here.