The SendSafely Dropzone API lets you easily build your own custom web form that uses end-to-end encryption to protect form data. If your Dropzone uses a webhook for notifications, submissions to this web form will invoke that webhook. If you are not already familiar with how our Dropzone API lets you build an encrypted web form, check out this blog post for an overview.
Once you're ready to implement your own web form, this article will guide you through the technical specifics of how to do so. We’ve also posted some live working examples on CodePen that you can use as a quick start template.
Building the HTML
The HTML form is relatively simple, and can be styled however you choose. The only elements we care about are the actual form inputs. A very simple form example is shown below. This form asks the user to provide their email address, tax ID number, and date of birth, and also allows them to attach one or more files.
<form id="dropzone_form" name="dropzone_form">
<div class="form-group">
<label for="name">Name</label> <input class="form-control" id="name" name="name" placeholder="Enter your full name" type="text">
</div>
<div class="form-group">
<label for="email">Email Address</label> <input type="email" class="form-control" id="email" name="email" placeholder="Enter your email address">
</div>
<div class="form-group">
<label for="secure_ssn">Tax ID Number</label> <span class="badge badge-pill badge-info" style="font-size:8px; margin-left:8px;">ENCRYPTED</span> <input class="form-control" id="secure_ssn" name="secure_ssn" placeholder="Enter your tax ID number" type="text">
</div>
<div class="form-group">
<label for="secure_dob">Date of Birth</label> <span class="badge badge-pill badge-info" style="font-size:8px; margin-left:8px;">ENCRYPTED</span> <input class="form-control" id="secure_dob" name="secure_dob" placeholder="Enter your date of birth" type="text">
</div>
<div class="form-group">
<span>Files</span>
<div id="dropzone-placeholder-div1"></div>
</div>
<div align="center">
<button class="btn btn-primary" id="sendsafely-submit" onclick="submitForm()" type="button">Submit <i class="fas fa-spinner fa-spin" id="spinner" style="display:none; margin-left:5px;"></i></button>
</div>
</form>
There are a few key points to note about the form HTML shown above:
-
The HTML form is given a unique ID and Name of “dropzone_form”. This will make it easy for us to reference this form from JavaScript later on in the example.
-
There are three text inputs on the form: Email, Tax ID, and Date of Birth. Those inputs are also each given a unique ID and Name of “email”, “secure_ssn” and “secure_dob” respectively.
-
The email value will NOT be encrypted since we will use that value to identify the user who submitted this information. The Tax ID and Date of Birth fields WILL be encrypted, which is why we preface the ID and Name values with “secure_”. This will make it easy for our Javascript to distinguish which form elements require encryption.
-
The “dropzone-placeholder-div” element is a placeholder where we want to render the drag-and-drop interface for users to attach encrypted files. If you do not want users to attach files, that element is not necessary.
-
When the form’s Submit button is pressed, we will invoke a custom JavaScript function called “submitForm()”.
Adding JavaScript
Next, we will take a look at some JavaScript that needs to be added to the page in order for the form to work properly. There are two main pieces of JavaScript code:
- A routine that initializes the Dropzone API when the page loads
- A function that gets called when the user presses the Submit button
Initialization JavaScript
The initialization JavaScript should be placed at the top of your page and should look something like the following:
<script>
var widget;
var sendSafelyHost = "your-sendsafely-host";
var dropzoneId = "your-dropzone-id";
var ready = (callback) => {
if (document.readyState != "loading") callback();
else document.addEventListener("DOMContentLoaded", callback);
}
ready(() => {
var placeholderElement = document.getElementById("dropzone-placeholder-div1");
var threadId = document.getElementById("dropzone-thread-id");
widget = new SendSafelyDropzone(dropzoneId, placeholderElement, undefined, threadId);
widget.url = sendSafelyHost;
widget.invokeDropzoneConnectors = true;
widget.disableAutoSubmit = true;
widget.initialize();
});
</script>
There are a few key points to note about this JavaScript:
-
Three variables are declared at the top of the script, which are accessible to all functions on the page (widget, sendsafelyHost and dropzoneId). You should replace the sendsafelyHost and dropzoneId with the hostname of your SendSafely portal (i.e., companyname.sendsafely.com) and your unique Dropzone ID. Your Dropzone ID can be obtained from the SendSafely "Edit Profile" screen once you enable your Dropzone. Steps on how to enable and configure the Dropzone can be found here.
-
The code within the ready callback function initializes the SendSafely widget using the Dropzone ID and references the unique placeholder DIV element from your HTML form.
- Although our example will use jQuery, the widget itself does not use or rely on jQuery.
Form Processing JavaScript
Last, you must define the JavaScript function that fires when the user presses the Submit button so that the form can be processed. This block of code includes a total of four functions:
- submitForm - Invoked when the user presses the Submit button.
- isFormValid - Handles form input validation (called by submitForm).
-
buildSecureMessage - Parses the encrypted form fields and builds the secure message payload (a utility function called by submitForm).
-
submitHostedDropzone - Invokes an endpoint on the SendSafely server that handles notifications as defined in your Hosted Dropzone configuration settings (a utility function called by submitForm). Refer to this article for information on the different notification options and how to configure them.
The code for these functions are below:
<script>
function isFormValid() {
var isValid = true;
if (!/(.+)@(.+){2,}\.(.+){2,}/.test(document.getElementById("email").value)) {
alert("You did not provide a valid email address");
isValid = false;
return isValid;
}
document.querySelectorAll("#dropzone_form input[type=text]").forEach((input) => {
if (isValid && input.value.trim() === "") {
alert("You must complete all input fields");
isValid = false;
return isValid;
}
});
if (isValid && widget.nbrOfFilesAttached < 1) {
alert("You did not attach a file");
isValid = false;
return isValid;
}
return isValid;
}
function buildSecureMessage() {
var secureMessage = "";
document.querySelectorAll("#dropzone_form input[type=text]").forEach((input) => {
if (input.name.startsWith("secure_")) {
// uncomment if you want to prepend the labelText to the secureMessage
/* if (input.name.startsWith("secure_")) {
var label = document.querySelector(("label[for='" + input.id + "']"));
var labelText = label ? label.textContent : "";
secureMessage += labelText + ": " + input.value + "\n"; */
secureMessage += input.value + "\n";
}
});
return secureMessage;
}
function submitForm() {
if (isFormValid()) {
var spinner = document.getElementById("spinner");
var submit_done = document.getElementById('submit_done');
// showing spinner
spinner.style.display = '';
var secureMessage = buildSecureMessage();
widget.packageLabel = document.getElementById('name').value;
widget.unconfirmedSender = document.getElementById('email').value.toLowerCase();
widget.addMessage(secureMessage);
widget.finalizePackage(
function(url) {
// success
// uncomment if not invoking dropzone connector and want to display package id
/* var threadRegex = new RegExp("thread=[A-Za-z0-9-]+");
var threadId = threadRegex.exec(url).toString().substr(7);
document.getElementById('dropzone-thread-id').textContent = threadId; */
document.getElementById('dropzone_form').style.display = 'none';
submit_done.style.display = '';
},
function() {
spinner.style.display = 'none';
}
);
}
}
</script>
A few points to note about the above functions:
-
The submitForm() function builds the secure message payload using buildSecureMessage() (see below for more information) and then calls the finalizePackage() method to finalize the SendSafely package. After the package is finalized, this function calls the submitHostedDropzone() function to handle notifications as configured for your Hosted Dropzone. The use of submitHostedDropzone() is optional but recommended unless you have your own endpoint that is capable of handling notifications for you.
-
The buildSecureMessage() function collects each name/value pair in the format “name: value” and compiles them into a SendSafely secure message payload separated by a new line between each pair. You have complete control over how the inputs are formatted and stored within SendSafely. For example, if you wanted store these values as JSON you could use $('#formid').serializeArray();
-
The submitHostedDropzone() function calls an endpoint on the SendSafely server that performs Drozpone notifications as they are configured for your Hosted Dropzone. This function should generally not be modified as it is designed to perform the exact same notifications that would happen when an item was submitted to your Hosted Dropzone. If you prefer to perform your own notification, you can omit this function and handle the secure link using your own custom endpoint.
Putting it all together
The complete HTML form and JavaScript are included below. Keep in mind that this example is minimalist and does not include and CSS styling or UI validation.
For more robust examples that can be adapted for use, check out our sample code posted on CodePen.
<html>
<script src="https://demo.sendsafely.com/js/external/SendSafelyDropzone.v2.js" type="module"></script>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<body>
<form id="dropzone_form" name="dropzone_form">
<div class="form-group">
<label for="name">Name</label> <input class="form-control" id="name" name="name" placeholder="Enter your full name" type="text">
</div>
<div class="form-group">
<label for="email">Email Address</label> <input type="email" class="form-control" id="email" name="email" placeholder="Enter your email address">
</div>
<div class="form-group">
<label for="secure_ssn">Tax ID Number</label> <span class="badge badge-pill badge-info" style="font-size:8px; margin-left:8px;">ENCRYPTED</span> <input class="form-control" id="secure_ssn" name="secure_ssn" placeholder="Enter your tax ID number" type="text">
</div>
<div class="form-group">
<label for="secure_dob">Date of Birth</label> <span class="badge badge-pill badge-info" style="font-size:8px; margin-left:8px;">ENCRYPTED</span> <input class="form-control" id="secure_dob" name="secure_dob" placeholder="Enter your date of birth" type="text">
</div>
<div class="form-group">
<span>Files</span>
<div id="dropzone-placeholder-div1"></div>
</div>
<div align="center">
<button class="btn btn-primary" id="sendsafely-submit" onclick="submitForm()" type="button">Submit <i class="fas fa-spinner fa-spin" id="spinner" style="display:none; margin-left:5px;"></i></button>
</div>
</form>
<script>
function isFormValid() {
var isValid = true;
if (!/(.+)@(.+){2,}\.(.+){2,}/.test(document.getElementById("email").value)) {
alert("You did not provide a valid email address");
isValid = false;
return isValid;
}
document.querySelectorAll("#dropzone_form input[type=text]").forEach((input) => {
if (isValid && input.value.trim() === "") {
alert("You must complete all input fields");
isValid = false;
return isValid;
}
});
if (isValid && widget.nbrOfFilesAttached < 1) {
alert("You did not attach a file");
isValid = false;
return isValid;
}
return isValid;
}
function buildSecureMessage() {
var secureMessage = "";
document.querySelectorAll("#dropzone_form input[type=text]").forEach((input) => {
if (input.name.startsWith("secure_")) {
// uncomment if you want to prepend the labelText to the secureMessage
/* if (input.name.startsWith("secure_")) {
var label = document.querySelector(("label[for='" + input.id + "']"));
var labelText = label ? label.textContent : "";
secureMessage += labelText + ": " + input.value + "\n"; */
secureMessage += input.value + "\n";
}
});
return secureMessage;
}
function submitForm() {
if (isFormValid()) {
var spinner = document.getElementById("spinner");
var submit_done = document.getElementById('submit_done');
// showing spinner
spinner.style.display = '';
var secureMessage = buildSecureMessage();
widget.packageLabel = document.getElementById('name').value;
widget.unconfirmedSender = document.getElementById('email').value.toLowerCase();
widget.addMessage(secureMessage);
widget.finalizePackage(
function(url) {
// success
// uncomment if not invoking dropzone connector and want to display package id
/* var threadRegex = new RegExp("thread=[A-Za-z0-9-]+");
var threadId = threadRegex.exec(url).toString().substr(7);
document.getElementById('dropzone-thread-id').textContent = threadId; */
document.getElementById('dropzone_form').style.display = 'none';
submit_done.style.display = '';
},
function() {
spinner.style.display = 'none';
}
);
}
}
</script>
<script>
var widget;
var sendSafelyHost = "your-sendsafely-host";
var dropzoneId = "your-dropzone-id";
var ready = (callback) => {
if (document.readyState != "loading") callback();
else document.addEventListener("DOMContentLoaded", callback);
}
ready(() => {
var placeholderElement = document.getElementById("dropzone-placeholder-div1");
var threadId = document.getElementById("dropzone-thread-id");
widget = new SendSafelyDropzone(dropzoneId, placeholderElement, undefined, threadId);
widget.url = sendSafelyHost;
widget.invokeDropzoneConnectors = true;
widget.disableAutoSubmit = true;
widget.initialize();
});
</script>
</body>
</html>
If you are a current SendSafely customer and would like assistance implementing your own custom web form, email us at support@sendsafely.com for help.
Comments
0 comments
Please sign in to leave a comment.