paint-brush
A Guide to Displaying Password Protected PDFs in a Web Applicationby@foxitsoftware
9,169 reads
9,169 reads

A Guide to Displaying Password Protected PDFs in a Web Application

by Foxit SoftwareJuly 6th, 2023
Read on Terminal Reader
Read this story w/o Javascript

Too Long; Didn't Read

Develop a Node application that harnesses the power of Foxit PDF SDK for Web. This integration allows you to effortlessly open password-protected PDFs directly in the browser. When the correct password is entered, users will be able to preview the file seamlessly. If an incorrect password is provided, an error message will be displayed, prompting users to retry.
featured image - A Guide to Displaying Password Protected PDFs in a Web Application
Foxit Software HackerNoon profile picture

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 JavaScript PDF library, presenting PDFs in a browser-based application becomes a seamless task. In this step-by-step tutorial, you will learn how to configure a Node application that harnesses the power of Foxit PDF SDK for Web. This integration allows you to effortlessly open password-protected PDFs directly in the browser, granting authorized users the ability to preview the documents. For those who prefer to skip the tutorial and access a fully functional version of the application, you can find it readily available on GitHub.

Building a Web Application to Display Password Protected PDFs

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 Express web framework for backend development, Pure CSS for styling purposes, and Foxit’s PDF SDK for integrating PDF functionality.

Prerequisites

Creating a New Express App

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.

Setting Up The Route

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.

Uploading and Displaying PDFs


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:

Handling Errors

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 documentation and a wide range of examples to assist you in building various applications.


It’s worth noting that Foxit provides PDF SDKs not only for web applications but also forother platforms such as mobile and native apps. This means you can utilize the power of Foxit PDF SDK across different environments, ensuring consistent and reliable PDF processing capabilities throughout your applications.


Also published here.