This is the third and final part of a multi-part series on building Single-Page Applications (SPAs) that integrate with the DocuSign Signature REST API via the CORS standard. Part 1 discussed the benefits of SPAs and why they need CORS. Part 2 discussed how to create private CORS gateways for your application to use. This post focuses on an example React application that uses your private CORS gateways to communicate with DocuSign.

As discussed in part 1 of this series, SPAs have taken the world of applications by storm to the point that it is now uncommon to use a consumer-oriented SAAS application that isn’t a single-page application. In the last couple of years, with the availability of SPA application frameworks like Angular-JS, React, and others, it is increasingly common for B-to-B and enterprise applications to also use SPA technology.

In preparation for this blog post, I took an on-line course about React and was able to successfully create my first React SPA in a couple of weeks. The application’s goals are:

Authenticate the user via the DocuSign OAuth Implicit Grant flow. Users should be automatically asked to authenticate themselves when they initiate an operation with the app and they are not yet authenticated or when their prior authentication period has timed out. If authentication is requested because the user has initiated an operation, then the operation should automatically resume after authentication is complete.

Operation 1: List the most recent 10 envelopes from the user’s DocuSign account, including the subject line, create date, and signing status of the envelopes.

Operation 2: Enable an order form to be filled in, an envelope to be created with the order information, and then signed using an embedded signing ceremony. After the order form is signed, the signer is returned to the application for any next steps.

Provide useful feedback to the user whenever the application is busy with a network request to DocuSign.

Three Network APIs

The SPA example uses three different network APIs:

The OAuth Implicit Grant flow is used to authenticate the user. This API uses HTTP redirect commands to shift the browser between the SPA and the authentication server. Because redirect commands are used, the Same Origin Policy does not apply and the CORS gateway is not involved.

After the access token is received, the SPA makes a GET request to the OAuth::userInfo API method. It returns information on the user associated with the access token: their name, email, account access and the DocuSign base path for each account. This API uses a private CORS gateway to reach account-d.docusign.com.

Lastly, the SPA makes calls to the eSignature REST API platform itself. Multiple calls are made to accomplish the SPA’s operations. A second CORS gateway is used for these communications to demo.docusign.net.

Production URLs

While developing your application with the sandbox (demo) DocuSign platform, account-d.docusign.com is the DocuSign Authentication service and demo.docusign.net is the eSignature REST API address. For production, use account.docusign.com for the authentication service. You will also use one or more of the DocuSign production URLs such as www.docusign.net, na2.docusign.net,or eu.docusign.net (this is a partial list), depending on the DocuSign accounts of your SPA’s users. You will need a different CORS gateway for each URL.

Implementing the React SPA

The example React application was built using the Create React App application. The example has not been ejected, so it is still under the control of react-scripts and can be easily updated.

Key files and methods in the React example

The React example uses the following files and methods to implement its key features:

The app uses redux to manage its state. Redux-thunk is used to enable redux actions to dispatch other actions and to call asynchronous methods including API requests.

The loading spinner UI element is implemented by the Loading component. It is controlled by the App container which uses the redux store’s loading.loadingMsg state variable to control it.

Similarly to the loading spinner, the alert messages are implemented by an AlertProvider third-party library. The element is added at the root level of the app in the index file. It is invoked by the App container, see line 22. It is controlled by the redux store’s loading.alertMsg state variable.

The Higher Order Container (hoc) CheckToken ensures that an unexpired access token is available when an operation’s page is first opened. If a good access token is not available then the user is asked to start the authentication flow after the intended operation’s url is stored for use after authentication has completed.

Authentication is initiated with the dsAuthStart action in the dsAuth container. Note how the action loads the web page URL from the DocuSign Authentication Service into the browser. Once this is done, the SPA is no longer running. After the authentication process has completed, the SPA is reloaded. When it first starts up, it checks the URL to see if the URL includes the access token (method checkHashToken in file dsAuth). If the token is included in the URL, then the method calls the OAuth::getInfo API method. Finally, the app loads the page that was in progress when authentication was initiated. This is done in the App container, line 30.

Whenever the SPA starts up and there isn’t an authentication token in the URL, the app looks in the browser’s LocalStorage to see if a previously stored token can be used. If not, then the SPA starts up and is not authenticated with DocuSign: the user will need to authenticate before a request can be made to DocuSign.

The application uses the listEnvelopesStart action in the listEnv action file to obtain the list of envelopes. The action first calls the DocuSign API method Envelopes::listStatusChanges, then uses the resulting list of envelopes to make Envelopes::get calls for each one. Since each API call is asynchronous, the method sets up a promise chain to make the calls.

To send an envelope and then sign it using an embedded signing ceremony, the application uses the sendSignEnvelopeStart method in the sendSignEnv action file. The method first calls Envelopes::create, and then obtains the signing ceremony url from EnvelopeViews::createRecipient. Finally, the browser is instructed to load the signing ceremony’s url.