From 838cec11cf89fd19d24074797d741a7bce4eaeef Mon Sep 17 00:00:00 2001 From: Aaron Wilde Date: Tue, 9 Jun 2020 20:10:05 -0700 Subject: [PATCH 1/5] initial commit --- .gitignore | 3 +- README.md | 94 +- config/appsettings.json | 21 + config/documentNames.json | 118 ++ config/documentOptions.json | 50 + config/github.json | 7 + config/index.js | 20 + docs/Adding_examples.md | 2 +- ds_configuration.js | 175 -- index.js | 51 +- lib/DSAuthCodeGrant.js | 35 +- lib/DSJwtAuth.js | 258 +++ lib/commonControllers.js | 24 +- lib/examples/eg001EmbeddedSigning.js | 69 +- lib/examples/eg002SigningViaEmail.js | 50 +- lib/examples/eg003ListEnvelopes.js | 20 +- lib/examples/eg004EnvelopeInfo.js | 22 +- lib/examples/eg005EnvelopeRecipients.js | 20 +- lib/examples/eg006EnvelopeDocs.js | 28 +- lib/examples/eg007EnvelopeGetDoc.js | 22 +- lib/examples/eg008CreateTemplate.js | 38 +- lib/examples/eg009UseTemplate.js | 44 +- lib/examples/eg010SendBinaryDocs.js | 72 +- lib/examples/eg011EmbeddedSending.js | 38 +- lib/examples/eg012EmbeddedConsole.js | 25 +- lib/examples/eg013AddDocToTemplate.js | 74 +- lib/examples/eg014CollectPayment.js | 56 +- lib/examples/eg015EnvelopeTabData.js | 22 +- lib/examples/eg016SetTabValues.js | 40 +- lib/examples/eg017SetTemplateTabValues.js | 50 +- lib/examples/eg018EnvelopeCustomFieldData.js | 22 +- lib/examples/eg019AccessCodeAuthentication.js | 26 +- lib/examples/eg020SmsAuthentication.js | 42 +- lib/examples/eg021PhoneAuthentication.js | 42 +- lib/examples/eg022KbaAuthentication.js | 40 +- lib/examples/eg023IdvAuthentication.js | 87 +- lib/examples/eg024CreatePermission.js | 140 ++ lib/examples/eg025PermissionSetUserGroup.js | 133 ++ .../eg026PermissionChangeSingleSetting.js | 129 ++ lib/examples/eg027DeletePermission.js | 112 ++ lib/examples/eg028CreateBrand.js | 117 ++ lib/examples/eg029ApplyBrandToEnvelope.js | 297 +++ lib/examples/eg030ApplyBrandToTemplate.js | 150 ++ lib/examples/eg031BulkSendEnvelopes.js | 244 +++ lib/utilities/README_utilities.md | 4 +- lib/utilities/updateSources.js | 18 +- package-lock.json | 1663 ----------------- package.json | 12 +- views/pages/ds_must_authenticate.ejs | 10 +- views/pages/examples/eg001EmbeddedSigning.ejs | 4 +- views/pages/examples/eg002SigningViaEmail.ejs | 4 +- views/pages/examples/eg003ListEnvelopes.ejs | 4 +- views/pages/examples/eg004EnvelopeInfo.ejs | 4 +- .../examples/eg005EnvelopeRecipients.ejs | 4 +- views/pages/examples/eg006EnvelopeDocs.ejs | 4 +- views/pages/examples/eg007EnvelopeGetDoc.ejs | 4 +- views/pages/examples/eg008CreateTemplate.ejs | 4 +- views/pages/examples/eg009UseTemplate.ejs | 4 +- views/pages/examples/eg010SendBinaryDocs.ejs | 4 +- views/pages/examples/eg011EmbeddedSending.ejs | 4 +- views/pages/examples/eg012EmbeddedConsole.ejs | 4 +- .../pages/examples/eg013AddDocToTemplate.ejs | 4 +- views/pages/examples/eg014CollectPayment.ejs | 4 +- views/pages/examples/eg015EnvelopeTabData.ejs | 4 +- views/pages/examples/eg016SetTabValues.ejs | 4 +- .../examples/eg017SetTemplateTabValues.ejs | 4 +- .../examples/eg018EnvelopeCustomFieldData.ejs | 4 +- .../eg019AccessCodeAuthentication.ejs | 4 +- .../pages/examples/eg020SmsAuthentication.ejs | 4 +- .../examples/eg021PhoneAuthentication.ejs | 29 +- .../pages/examples/eg022KbaAuthentication.ejs | 64 +- .../pages/examples/eg023IdvAuthentication.ejs | 45 +- .../pages/examples/eg024CreatePermission.ejs | 26 + .../examples/eg025PermissionSetUserGroup.ejs | 42 + .../eg026PermissionChangeSingleSetting.ejs | 104 ++ .../pages/examples/eg027DeletePermission.ejs | 41 + views/pages/examples/eg028CreateBrand.ejs | 39 + .../examples/eg029ApplyBrandToEnvelope.ejs | 57 + .../examples/eg030ApplyBrandToTemplate.ejs | 78 + .../pages/examples/eg031BulkSendEnvelopes.ejs | 79 + views/pages/index.ejs | 8 +- views/pages/index_examples.ejs | 70 +- views/partials/docBody.ejs | 3 + views/partials/head.ejs | 3 +- 84 files changed, 3070 insertions(+), 2534 deletions(-) create mode 100644 config/appsettings.json create mode 100644 config/documentNames.json create mode 100644 config/documentOptions.json create mode 100644 config/github.json create mode 100644 config/index.js delete mode 100644 ds_configuration.js create mode 100644 lib/DSJwtAuth.js create mode 100644 lib/examples/eg024CreatePermission.js create mode 100644 lib/examples/eg025PermissionSetUserGroup.js create mode 100644 lib/examples/eg026PermissionChangeSingleSetting.js create mode 100644 lib/examples/eg027DeletePermission.js create mode 100644 lib/examples/eg028CreateBrand.js create mode 100644 lib/examples/eg029ApplyBrandToEnvelope.js create mode 100644 lib/examples/eg030ApplyBrandToTemplate.js create mode 100644 lib/examples/eg031BulkSendEnvelopes.js delete mode 100644 package-lock.json create mode 100644 views/pages/examples/eg024CreatePermission.ejs create mode 100644 views/pages/examples/eg025PermissionSetUserGroup.ejs create mode 100644 views/pages/examples/eg026PermissionChangeSingleSetting.ejs create mode 100644 views/pages/examples/eg027DeletePermission.ejs create mode 100644 views/pages/examples/eg028CreateBrand.ejs create mode 100644 views/pages/examples/eg029ApplyBrandToEnvelope.ejs create mode 100644 views/pages/examples/eg030ApplyBrandToTemplate.ejs create mode 100644 views/pages/examples/eg031BulkSendEnvelopes.ejs create mode 100644 views/partials/docBody.ejs diff --git a/.gitignore b/.gitignore index 85c6122e..fa406e31 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ typings/ # ignore config file */ds_configuration.js +secret # ignore vs settings -.vs \ No newline at end of file +.vs diff --git a/README.md b/README.md index 6a1ff117..482b279a 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,9 @@ -# Node.JS: Authorization Code Grant Examples +# Node.JS Launcher Code Examples -### Github repo: eg-03-node-auth-code-grant +### Github repo: [code-examples-nodejs](./) ## Introduction This repo is a Node.JS application that demonstrates: -* Authentication with DocuSign via the -[Authorization Code Grant flow](https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-code-grant). -When the token expires, the user is asked to re-authenticate. -The **refresh token** is not used in this example. - - - -## API version 2.1 - 1. **Embedded Signing Ceremony.** [Source.](./lib/examples/eg001EmbeddedSigning.js) This example sends an envelope, and then uses an embedded signing ceremony for the first signer. @@ -87,16 +78,58 @@ The **refresh token** is not used in this example. 1. **Requiring ID Verification (IDV) for a recipient** [Source.](./lib/examples/eg023IdvAuthentication.js) This example sends and envelope that requires the recipient to upload a government issued id. +1. **Creating a permission profile** + [Source.](./lib/examples/eg024CreatePermission.js) + This code example demonstrates how to create a permission profile using the [Create Permission Profile](https://developers.docusign.com/esign-rest-api/reference/Accounts/AccountPermissionProfiles/create) method. +1. **Setting a permission profile** + [Source.](./lib/examples/eg025PermissionSetUserGroup.js) + This code example demonstrates how to set a user group's permission profile using the [Update Group](https://developers.docusign.com/esign-rest-api/reference/UserGroups/Groups/update) method. + You must have already created permissions profile and group of users. +1. **Updating individual permission settings** + [Source.](./lib/examples/eg026PermissionChangeSingleSetting.js) + This code example demonstrates how to edit individual permission settings on a permissions profile using the [Update Permission Profile](https://developers.docusign.com/esign-rest-api/reference/Accounts/AccountPermissionProfiles/update) method. +1. **Deleting a permission profile** + [Source.](./lib/examples/eg027DeletePermission.js) + This code example demonstrates how to delete a permission profile using the [Delete Permission Profile](https://developers.docusign.com/esign-rest-api/reference/Accounts/AccountPermissionProfiles/create) method. +1. **Creating a brand** + [Source.](./lib/examples/eg028CreateBrand.js) + This example creates brand profile for an account using the [Create Brand](https://developers.docusign.com/esign-rest-api/reference/Accounts/AccountBrands/create) method. +1. **Applying a brand to an envelope** + [Source.](./lib/examples/eg029ApplyBrandToEnvelope.js) + This code example demonstrates how to apply a brand you've created to an envelope using the [Create Envelope](https://developers.docusign.com/esign-rest-api/reference/Envelopes/Envelopes/create) method. + First, creates the envelope and then applies brand to it. + Anchor text ([AutoPlace](https://support.docusign.com/en/guides/AutoPlace-New-DocuSign-Experience)) is used to position the signing fields in the documents. +1. **Applying a brand to a template** + [Source.](./lib/examples/eg030ApplyBrandToTemplate.js) + This code example demonstrates how to apply a brand you've created to a template using using the [Create Envelope](https://developers.docusign.com/esign-rest-api/reference/Envelopes/Envelopes/create) method. + You must have at least one created template and brand. + Anchor text ([AutoPlace](https://support.docusign.com/en/guides/AutoPlace-New-DocuSign-Experience)) is used to position the signing fields in the documents. +1. **Bulk sending envelopes to multiple recipients** + [Source.](./lib/examples/eg031BulkSendEnvelopes.js) + This code example demonstrates how to send envelopes in bulk to multiple recipients using these methods: + [Create Bulk Send List](https://developers.docusign.com/esign-rest-api/reference/BulkEnvelopes/BulkSend/createBulkSendList), + [Create Bulk Send Request](https://developers.docusign.com/esign-rest-api/reference/BulkEnvelopes/BulkSend/createBulkSendRequest). + Firstly, creates a bulk send recipients list, and then creates an envelope. + After that, initiates bulk envelope sending. + +## Included OAuth grant types: + +* Authentication with Docusign via [Authorization Code Grant flow](https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-code-grant) . +When the token expires, the user is asked to re-authenticate. +The **refresh token** is not used in this example. + +* Authentication with DocuSign via the [JSON Web Token (JWT) Grant](https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken). +When the token expires, it updates automatically. + ## Installation ### Prerequisites 1. A DocuSign Developer Sandbox account (email and password) on [demo.docusign.net](https://demo.docusign.net). Create a [free account](https://go.docusign.com/sandbox/productshot/?elqCampaignId=16534). -1. A DocuSign Integration Key (a client ID) that is configured to use the - OAuth Authorization Code flow. - You will need the **Integration Key** itself, and its **secret**. + +1. A DocuSign Integration Key (a client ID). To use Authorization code grant, you will need the **Integration Key** itself, and its **secret**. To use JSON Web token, you will need the **Integration Key** itself, the **RSA Secret Key** and an API user ID for the user you are impersonating. If you use this example on your own workstation, the Integration key must include a **Redirect URI** of `http://localhost:5000/ds/callback` @@ -109,35 +142,47 @@ The **refresh token** is not used in this example. The signer and the cc email cannot be the same. ### Installation steps -1. Download or clone this repository to your workstation to directory **eg-03-node-auth-code-grant** -1. **cd eg-03-node-auth-code-grant** +1. Download or clone this repository to your workstation to directory **code-examples-nodejs** +1. **cd code-examples-nodejs** 1. **npm install** 1. *Either:* - * Update the file **ds_configuration.js** in the project's root directory + * Update the file **config/appsettings.json** in the project's root directory with the Integration Key and other settings, *or* * Create and export environment variables for the settings. - See the **ds_configuration.js** file + See the **config/appsettings.json** file for the names of the environment variables. **Note:** Protect your Integration Key and secret--If you update - the ds_configuration.js file, then you + the config/appsettings.json file, then you should ensure that it will not be stored in your source code repository. 1. **npm start** 1. Open a browser to **http://localhost:5000** +### Configuring JWT + +1. Create a developer sandbox account on developers.docusign.com if you don't already have one. +2. Create a new API key in the Admin panel: https://admindemo.docusign.com/api-integrator-key, take note of the public key. +3. Set a redirect URI of `http://localhost:5000/ds/callback` as mentioned in the installation steps above for the API key you make in step 2. +4. Generate an RSA keypair in the administrator console on the DocuSign developer sandbox and copy the private key to a secure location. +5. Create a new file in your repo source folder named **private.key**, and paste in that copied RSA private key, then save it. +6. Update the file **config/appsettings.json** and include the newly created API key from step 2 as well as your account user id GUID which is also found on the Admin panel: `https://admindemo.docusign.com/api-integrator-key`. + +From there you should be able to run the launcher using **npm start** then selecting **JSON Web Token** when authenticaing your account. + + #### Payments code example To use the payments example, create a test payments gateway for your developer sandbox account. See the -[PAYMENTS_INSTALLATION.md](./PAYMENTS_INSTALLATION.md) +[PAYMENTS_INSTALLATION.md](./eg-03-node-auth-code-grant/blob/master/PAYMENTS_INSTALLATION.md) file for instructions. -Then add the payment gateway account id to the **ds_configuration.js** file. +Then add the payment gateway account id to the **config/appsettings.json** file. ## Using the examples with other authentication flows @@ -154,10 +199,3 @@ This repository uses the MIT License. See the LICENSE file for more information. ### Pull Requests Pull requests are welcomed. Pull requests will only be considered if their content uses the MIT License. - -### Additional Resources -* [DocuSign Developer Center](https://developers.docusign.com) -* [DocuSign API on Twitter](https://twitter.com/docusignapi) -* [DocuSign For Developers on LinkedIn](https://www.linkedin.com/showcase/docusign-for-developers/) -* [DocuSign For Developers on YouTube](https://www.youtube.com/channel/UCJSJ2kMs_qeQotmw4-lX2NQ) - diff --git a/config/appsettings.json b/config/appsettings.json new file mode 100644 index 00000000..3ca38d9c --- /dev/null +++ b/config/appsettings.json @@ -0,0 +1,21 @@ +{ + "dsClientId": "{CLIENT_ID}", + "dsClientSecret": "{CLIENT_SECRET}", + "signerEmail": "{USER_EMAIL}", + "signerName": "{USER_FULLNAME}", + "appUrl": "http://localhost:5000", + "production": false, + "debug": true, + "sessionSecret": "12345", + "allowSilentAuthentication": true, + "targetAccountId": null, + "demoDocPath": "demo_documents", + "docDocx": "World_Wide_Corp_Battle_Plan_Trafalgar.docx", + "docPdf": "World_Wide_Corp_lorem.pdf", + "gatewayAccountId": "", + "gatewayName": "stripe", + "gatewayDisplayName": "Stripe", + "githubExampleUrl": "https://github.com/docusign/eg-03-node-auth-code-grant/tree/master/lib/examples/", + "documentation": null, + "multiSourceChooser": false +} \ No newline at end of file diff --git a/config/documentNames.json b/config/documentNames.json new file mode 100644 index 00000000..7b96ec34 --- /dev/null +++ b/config/documentNames.json @@ -0,0 +1,118 @@ +{ + "node": { + "eg001": "eg001EmbeddedSigning.js", + "eg002": "eg002SigningViaEmail.js", + "eg003": "eg003ListEnvelopes.js", + "eg004": "eg004EnvelopeInfo.js", + "eg005": "eg005EnvelopeRecipients.js", + "eg006": "eg006EnvelopeDocs.js", + "eg007": "eg007EnvelopeGetDoc.js", + "eg008": "eg008CreateTemplate.js", + "eg009": "eg009UseTemplate.js", + "eg010": "eg010SendBinaryDocs.js", + "eg011": "eg011EmbeddedSending.js", + "eg012": "eg012EmbeddedConsole.js", + "eg013": "eg013AddDocToTemplate.js", + "eg014": "eg014CollectPayment.js", + "eg015": "eg015EnvelopeTabData.js", + "eg016": "eg016SetTabValues.js", + "eg017": "eg017SetTemplateTabValues.js", + "eg018": "eg018EnvelopeCustomFieldData.js", + "eg019": "eg019AccessCodeAuthentication.js", + "eg020": "eg020SmsAuthentication.js", + "eg021": "eg021PhoneAuthentication.js", + "eg022": "eg022KbaAuthentication.js", + "eg023": "eg023IdvAuthentication.js", + "eg024": "eg024CreateBrand.js", + "eg025": "eg025ApplyBrandToEnvelope.js", + "eg026": "eg026ApplyBrandToTemplate.js", + "eg027": "eg027PermissionChangeSingleSetting.js", + "eg028": "eg028CreatePermission.js", + "eg029": "eg029DeletePermission.js", + "eg030": "eg030PermissionSetUserGroup.js", + "eg031": "eg031BulkSendEnvelopes.js" + }, + "java": { + "eg001": "EG001ControllerEmbeddedSigning.java", + "eg002": "EG002ControllerSigningViaEmail.java", + "eg003": "EG003ControllerListEnvelopes.java", + "eg004": "EG004ControllerEnvelopeInfo.java", + "eg005": "EG005ControllerEnvelopeRecipients.java", + "eg006": "EG006ControllerEnvelopeDocs.java", + "eg007": "EG007ControllerEnvelopeGetDoc.java", + "eg008": "EG008ControllerCreateTemplate.java", + "eg009": "EG009ControllerUseTemplate.java", + "eg010": "EG010ControllerSendBinaryDocs.java", + "eg011": "EG011ControllerEmbeddedSending.java", + "eg012": "EG012ControllerEmbeddedConsole.java", + "eg013": "EG013ControllerAddDocToTemplate.java", + "eg014": "EG014ControllerCollectPayment.java" + }, + "curl": { + "eg001": "eg001EmbeddedSigning.sh", + "eg002": "eg002SigningViaEmail.sh", + "eg003": "eg003ListEnvelopes.sh", + "eg004": "eg004EnvelopeInfo.sh", + "eg005": "eg005EnvelopeRecipients.sh", + "eg006": "eg006EnvelopeDocs.sh", + "eg007": "eg007EnvelopeGetDoc.sh", + "eg008": "eg008CreateTemplate.sh", + "eg009": "eg009UseTemplate.sh", + "eg010": "eg010SendBinaryDocs.sh", + "eg011": "eg011EmbeddedSending.sh", + "eg012": "eg012EmbeddedConsole.sh", + "eg013": "eg013AddDocToTemplate.sh", + "eg014": "eg014CollectPayment.sh" + }, + "php": { + "eg001": "EG001EmbeddedSigning.php", + "eg002": "EG002SigningViaEmail.php", + "eg003": "EG003ListEnvelopes.php", + "eg004": "EG004EnvelopeInfo.php", + "eg005": "EG005EnvelopeRecipients.php", + "eg006": "EG006EnvelopeDocs.php", + "eg007": "EG007EnvelopeGetDoc.php", + "eg008": "EG008CreateTemplate.php", + "eg009": "EG009UseTemplate.php", + "eg010": "EG010SendBinaryDocs.php", + "eg011": "EG011EmbeddedSending.php", + "eg012": "EG012EmbeddedConsole.php", + "eg013": "EG013AddDocToTemplate.php", + "eg015": "EG015EnvelopeTabData.php", + "eg016": "EG016SetTabValues.php", + "eg017": "EG017SetTemplateTabValues.php", + "eg018": "EG018EnvelopeCustomFieldData.php" + }, + "python": { + "eg001": "eg001_embedded_signing.py", + "eg002": "eg002_signing_via_email.py", + "eg003": "eg003_list_envelopes.py", + "eg004": "eg004_envelope_info.py", + "eg005": "eg005_envelope_recipients.py", + "eg006": "eg006_envelope_docs.py", + "eg007": "eg007_envelope_get_doc.py", + "eg008": "eg008_create_template.py", + "eg009": "eg009_use_template.py", + "eg010": "eg010_send_binary_docs.py", + "eg011": "eg011_embedded_sending.py", + "eg012": "eg012_embedded_console.py", + "eg013": "eg013_add_doc_to_template.py", + "eg014": "eg014_collect_payment.py" + }, + "csharp": { + "eg001": "Eg001EmbeddedSigningController.cs", + "eg002": "Eg002SigningViaEmailController.cs", + "eg003": "Eg003ListEnvelopesController.cs", + "eg004": "Eg004EnvelopeInfoController.cs", + "eg005": "Eg005EnvelopeRecipientsController.cs", + "eg006": "Eg006EnvelopeDocsController.cs", + "eg007": "Eg007EnvelopeGetDocController.cs", + "eg008": "Eg008CreateTemplateController.cs", + "eg009": "Eg009UseTemplateController.cs", + "eg010": "Eg010SendBinaryDocsController.cs", + "eg011": "Eg011EmbeddedSendingController.cs", + "eg012": "Eg012EmbeddedConsoleController.cs", + "eg013": "Eg013AddDocToTemplateController.cs", + "eg014": "Eg014CollectPaymentController.cs" + } +} \ No newline at end of file diff --git a/config/documentOptions.json b/config/documentOptions.json new file mode 100644 index 00000000..455d3b6d --- /dev/null +++ b/config/documentOptions.json @@ -0,0 +1,50 @@ +[ + { + "langCode": "csharp", + "name": "C#", + "githubExampleUrl": "https://github.com/docusign/eg-03-csharp-auth-code-grant-core/tree/master/eg-03-csharp-auth-code-grant-core/Controllers/", + "owner": "docusign", + "repo": "eg-03-csharp-auth-code-grant-core", + "pathPrefix": "eg-03-csharp-auth-code-grant-core/Controllers/" + }, + { + "langCode": "php", + "name": "PHP", + "githubExampleUrl": "https://github.com/docusign/eg-03-php-auth-code-grant/blob/master/src/", + "owner": "docusign", + "repo": "eg-03-php-auth-code-grant", + "pathPrefix": "src/" + }, + { + "langCode": "java", + "name": "Java", + "githubExampleUrl": "https://github.com/docusign/eg-03-java-auth-code-grant/tree/master/src/main/java/com/docusign/controller/examples/", + "owner": "docusign", + "repo": "eg-03-java-auth-code-grant", + "pathPrefix": "src/main/java/com/docusign/controller/examples/" + }, + { + "langCode": "node", + "name": "Node.js", + "githubExampleUrl": "https://github.com/docusign/eg-03-node-auth-code-grant/tree/master/lib/examples/", + "owner": "docusign", + "repo": "eg-03-node-auth-code-grant", + "pathPrefix": "lib/examples/" + }, + { + "langCode": "curl", + "name": "API / curl", + "githubExampleUrl": "https://github.com/docusign/eg-03-curl/tree/master/examples/", + "owner": "docusign", + "repo": "eg-03-curl", + "pathPrefix": "examples/" + }, + { + "langCode": "python", + "name": "Python", + "githubExampleUrl": "https://github.com/docusign/eg-03-python-auth-code-grant/tree/master/app/", + "owner": "docusign", + "repo": "eg-03-python-auth-code-grant", + "pathPrefix": "app/" + } +] \ No newline at end of file diff --git a/config/github.json b/config/github.json new file mode 100644 index 00000000..0760ecf0 --- /dev/null +++ b/config/github.json @@ -0,0 +1,7 @@ +{ + "UserAgent": "Example Source Updater", + "AppId": 0, + "ApiUrl": "https://api.github.com/", + "InstallationId": 0, + "PrivateKey": "" +} \ No newline at end of file diff --git a/config/index.js b/config/index.js new file mode 100644 index 00000000..2635c4a1 --- /dev/null +++ b/config/index.js @@ -0,0 +1,20 @@ +exports.docOptions = require('./documentOptions.json'); +exports.docNames = require('./documentNames.json'); +const settings = require('./appsettings.json'); +exports.github = require('./github.json'); + +const dsOauthServer = settings.production + ? 'https://account.docusign.com' + : 'https://account-d.docusign.com'; + +settings.gatewayAccountId = process.env.DS_PAYMENT_GATEWAY_ID || settings.gatewayAccountId; +settings.dsClientSecret = process.env.DS_CLIENT_SECRET || settings.dsClientSecret; +settings.signerEmail = process.env.DS_SIGNER_EMAIL || settings.signerEmail; +settings.signerName = process.env.DS_SIGNER_NAME || settings.signerName; +settings.dsClientId = process.env.DS_CLIENT_ID || settings.dsClientId; +settings.appUrl = process.env.DS_APP_URL || settings.appUrl; + +exports.config = { + dsOauthServer, + ...settings +}; diff --git a/docs/Adding_examples.md b/docs/Adding_examples.md index 60f8d2d4..8d1ff023 100644 --- a/docs/Adding_examples.md +++ b/docs/Adding_examples.md @@ -87,7 +87,7 @@ see lib/examples/eg002.js and its use of the example_done.ejs view. ### Configuration information If additional configuration settings are needed, update the -`ds_configuration.js` file. +`config/appsettings.json` file. While developing and testing, be careful not to let any of your private information become stored in your repo. diff --git a/ds_configuration.js b/ds_configuration.js deleted file mode 100644 index 837e4f34..00000000 --- a/ds_configuration.js +++ /dev/null @@ -1,175 +0,0 @@ -// ds_configuration.js -- configuration information -// Either fill in the data below or set the environment variables -// -exports.config = { - dsClientId: process.env.DS_CLIENT_ID || '{CLIENT_ID}' // The app's DocuSign integration key - , dsClientSecret: process.env.DS_CLIENT_SECRET || '{CLIENT_SECRET}' // The app's DocuSign integration key's secret - , signerEmail: process.env.DS_SIGNER_EMAIL || '{USER_EMAIL}' - , signerName: process.env.DS_SIGNER_NAME || '{USER_FULLNAME}' - , appUrl: process.env.DS_APP_URL || 'http://localhost:5000' // The url of the application. Eg http://localhost:5000 - // NOTE: You must add a Redirect URI of appUrl/ds/callback to your Integration Key. - // Example: http://localhost:5000/ds/callback - , production: false - , debug: true // Send debugging statements to console - , sessionSecret: '12345' // Secret for encrypting session cookie content - , allowSilentAuthentication: true // a user can be silently authenticated if they have an - // active login session on another tab of the same browser - , targetAccountId: null // Set if you want a specific DocuSign AccountId, If null, the user's default account will be used. - , demoDocPath: 'demo_documents' - , docDocx: 'World_Wide_Corp_Battle_Plan_Trafalgar.docx' - , docPdf: 'World_Wide_Corp_lorem.pdf' - // Payment gateway information is optional - , gatewayAccountId: process.env.DS_PAYMENT_GATEWAY_ID || '{DS_PAYMENT_GATEWAY_ID}' - , gatewayName: "stripe" - , gatewayDisplayName: "Stripe" - , githubExampleUrl: 'https://github.com/docusign/eg-03-node-auth-code-grant/tree/master/lib/examples/' - , documentation: null - //, documentation: 'https://developers.docusign.com/esign-rest-api/code-examples/' - // Should source files for different software languages be shown? - , multiSourceChooser: false - , docOptions: [ - {langCode: 'csharp', name: 'C#', - githubExampleUrl: 'https://github.com/docusign/eg-03-csharp-auth-code-grant-core/tree/master/eg-03-csharp-auth-code-grant-core/Controllers/', - owner: 'docusign', repo: 'eg-03-csharp-auth-code-grant-core', pathPrefix: 'eg-03-csharp-auth-code-grant-core/Controllers/' - }, - {langCode: 'php', name: 'PHP', - githubExampleUrl: 'https://github.com/docusign/eg-03-php-auth-code-grant/blob/master/src/', - owner: 'docusign', repo: 'eg-03-php-auth-code-grant', pathPrefix: 'src/' - }, - {langCode: 'java', name: 'Java', - githubExampleUrl: 'https://github.com/docusign/eg-03-java-auth-code-grant/tree/master/src/main/java/com/docusign/controller/examples/', - owner: 'docusign', repo: 'eg-03-java-auth-code-grant', pathPrefix: 'src/main/java/com/docusign/controller/examples/' - }, - {langCode: 'node', name: 'Node.js', - githubExampleUrl: 'https://github.com/docusign/eg-03-node-auth-code-grant/tree/master/lib/examples/', - owner: 'docusign', repo: 'eg-03-node-auth-code-grant', pathPrefix: 'lib/examples/' - }, - {langCode: 'curl', name: 'API / curl', - githubExampleUrl: 'https://github.com/docusign/eg-03-curl/tree/master/examples/', - owner: 'docusign', repo: 'eg-03-curl', pathPrefix: 'examples/' - }, - {langCode: 'python', name: 'Python', - githubExampleUrl: 'https://github.com/docusign/eg-03-python-auth-code-grant/tree/master/app/', - owner: 'docusign', repo: 'eg-03-python-auth-code-grant', pathPrefix: 'app/' - }, - ] - , docNames: { - node: { - eg001: 'eg001EmbeddedSigning.js' - , eg002: 'eg002SigningViaEmail.js' - , eg003: 'eg003ListEnvelopes.js' - , eg004: 'eg004EnvelopeInfo.js' - , eg005: 'eg005EnvelopeRecipients.js' - , eg006: 'eg006EnvelopeDocs.js' - , eg007: 'eg007EnvelopeGetDoc.js' - , eg008: 'eg008CreateTemplate.js' - , eg009: 'eg009UseTemplate.js' - , eg010: 'eg010SendBinaryDocs.js' - , eg011: 'eg011EmbeddedSending.js' - , eg012: 'eg012EmbeddedConsole.js' - , eg013: 'eg013AddDocToTemplate.js' - , eg014: 'eg014CollectPayment.js' - , eg015: 'eg015EnvelopeTabData.js' - , eg016: 'eg016SetTabValues.js' - , eg017: 'eg017SetTemplateTabValues.js' - , eg018: 'eg018EnvelopeCustomFieldData.js' - , eg019: 'eg019AccessCodeAuthentication.js' - , eg020: 'eg020SmsAuthentication.js' - , eg021: 'eg021PhoneAuthentication.js' - , eg022: 'eg022KbaAuthentication.js' - , eg023: 'eg023IdvAuthentication.js' - }, - java: { - eg001: 'EG001ControllerEmbeddedSigning.java' - , eg002: 'EG002ControllerSigningViaEmail.java' - , eg003: 'EG003ControllerListEnvelopes.java' - , eg004: 'EG004ControllerEnvelopeInfo.java' - , eg005: 'EG005ControllerEnvelopeRecipients.java' - , eg006: 'EG006ControllerEnvelopeDocs.java' - , eg007: 'EG007ControllerEnvelopeGetDoc.java' - , eg008: 'EG008ControllerCreateTemplate.java' - , eg009: 'EG009ControllerUseTemplate.java' - , eg010: 'EG010ControllerSendBinaryDocs.java' - , eg011: 'EG011ControllerEmbeddedSending.java' - , eg012: 'EG012ControllerEmbeddedConsole.java' - , eg013: 'EG013ControllerAddDocToTemplate.java' - , eg014: 'EG014ControllerCollectPayment.java' - }, - curl: { - eg001: 'eg001EmbeddedSigning.sh' - , eg002: 'eg002SigningViaEmail.sh' - , eg003: 'eg003ListEnvelopes.sh' - , eg004: 'eg004EnvelopeInfo.sh' - , eg005: 'eg005EnvelopeRecipients.sh' - , eg006: 'eg006EnvelopeDocs.sh' - , eg007: 'eg007EnvelopeGetDoc.sh' - , eg008: 'eg008CreateTemplate.sh' - , eg009: 'eg009UseTemplate.sh' - , eg010: 'eg010SendBinaryDocs.sh' - , eg011: 'eg011EmbeddedSending.sh' - , eg012: 'eg012EmbeddedConsole.sh' - , eg013: 'eg013AddDocToTemplate.sh' - , eg014: 'eg014CollectPayment.sh' - }, - php: { - eg001: 'EG001EmbeddedSigning.php' - , eg002: 'EG002SigningViaEmail.php' - , eg003: 'EG003ListEnvelopes.php' - , eg004: 'EG004EnvelopeInfo.php' - , eg005: 'EG005EnvelopeRecipients.php' - , eg006: 'EG006EnvelopeDocs.php' - , eg007: 'EG007EnvelopeGetDoc.php' - , eg008: 'EG008CreateTemplate.php' - , eg009: 'EG009UseTemplate.php' - , eg010: 'EG010SendBinaryDocs.php' - , eg011: 'EG011EmbeddedSending.php' - , eg012: 'EG012EmbeddedConsole.php' - , eg013: 'EG013AddDocToTemplate.php' - //, eg014: 'EG014CollectPayment.php' - , eg015: 'EG015EnvelopeTabData.php' - , eg016: 'EG016SetTabValues.php' - , eg017: 'EG017SetTemplateTabValues.php' - , eg018: 'EG018EnvelopeCustomFieldData.php' - }, - python: { - eg001: 'eg001_embedded_signing.py' - , eg002: 'eg002_signing_via_email.py' - , eg003: 'eg003_list_envelopes.py' - , eg004: 'eg004_envelope_info.py' - , eg005: 'eg005_envelope_recipients.py' - , eg006: 'eg006_envelope_docs.py' - , eg007: 'eg007_envelope_get_doc.py' - , eg008: 'eg008_create_template.py' - , eg009: 'eg009_use_template.py' - , eg010: 'eg010_send_binary_docs.py' - , eg011: 'eg011_embedded_sending.py' - , eg012: 'eg012_embedded_console.py' - , eg013: 'eg013_add_doc_to_template.py' - , eg014: 'eg014_collect_payment.py' - }, - csharp: { - eg001: 'Eg001EmbeddedSigningController.cs' - , eg002: 'Eg002SigningViaEmailController.cs' - , eg003: 'Eg003ListEnvelopesController.cs' - , eg004: 'Eg004EnvelopeInfoController.cs' - , eg005: 'Eg005EnvelopeRecipientsController.cs' - , eg006: 'Eg006EnvelopeDocsController.cs' - , eg007: 'Eg007EnvelopeGetDocController.cs' - , eg008: 'Eg008CreateTemplateController.cs' - , eg009: 'Eg009UseTemplateController.cs' - , eg010: 'Eg010SendBinaryDocsController.cs' - , eg011: 'Eg011EmbeddedSendingController.cs' - , eg012: 'Eg012EmbeddedConsoleController.cs' - , eg013: 'Eg013AddDocToTemplateController.cs' - , eg014: 'Eg014CollectPaymentController.cs' - } - } - // The gitHub settings are for the lib/utilities software. - // They are reserved for use by DocuSign. - , ghUserAgent: 'Example Source Updater' - , gitHubAppId: 0 - , gitHubInstallationId: 0 - , gitHubPrivateKey: `` - } - exports.config.dsOauthServer = exports.config.production ? - 'https://account.docusign.com' : 'https://account-d.docusign.com'; \ No newline at end of file diff --git a/index.js b/index.js index 6524840c..dd8561ec 100755 --- a/index.js +++ b/index.js @@ -7,9 +7,12 @@ const express = require('express') , MemoryStore = require('memorystore')(session) // https://github.com/roccomuso/memorystore , path = require('path') , DSAuthCodeGrant = require('./lib/DSAuthCodeGrant') + , DsJwtAuth = require('./lib/dsJwtAuth') , passport = require('passport') , DocusignStrategy = require('passport-docusign') - , dsConfig = require('./ds_configuration.js').config + , docOptions = require('./config/documentOptions.json') + , docNames = require('./config/documentNames.json') + , dsConfig = require('./config/index.js').config , commonControllers = require('./lib/commonControllers') , flash = require('express-flash') , helmet = require('helmet') // https://expressjs.com/en/advanced/best-practice-security.html @@ -38,6 +41,14 @@ const express = require('express') , eg021 = require('./lib/examples/eg021PhoneAuthentication') , eg022 = require('./lib/examples/eg022KbaAuthentication') , eg023 = require('./lib/examples/eg023IdvAuthentication') + , eg024 = require('./lib/examples/eg024CreatePermission') + , eg025 = require('./lib/examples/eg025PermissionSetUserGroup') + , eg026 = require('./lib/examples/eg026PermissionChangeSingleSetting') + , eg027 = require('./lib/examples/eg027DeletePermission') + , eg028 = require('./lib/examples/eg028CreateBrand') + , eg029 = require('./lib/examples/eg029ApplyBrandToEnvelope') + , eg030 = require('./lib/examples/eg030ApplyBrandToTemplate') + , eg031 = require('./lib/examples/eg031BulkSendEnvelopes') ; const PORT = process.env.PORT || 5000 @@ -68,20 +79,28 @@ let app = express() .use(((req, res, next) => { res.locals.user = req.user; res.locals.session = req.session; - res.locals.dsConfig = dsConfig; + res.locals.dsConfig = { ...dsConfig, docOptions: docOptions, docNames: docNames }; res.locals.hostUrl = hostUrl; // Used by DSAuthCodeGrant#logout next()})) // Send user info to views .use(flash()) .set('views', path.join(__dirname, 'views')) .set('view engine', 'ejs') // Add an instance of DSAuthCodeGrant to req - .use((req, res, next) => {req.dsAuthCodeGrant = new DSAuthCodeGrant(req); next()}) + .use((req, res, next) => { + req.dsAuthCodeGrant = new DSAuthCodeGrant(req); + req.dsAuthJwt = new DsJwtAuth(req); + req.dsAuth = req.dsAuthCodeGrant; + if(req.session.authMethod === 'jwt-auth') { + req.dsAuth = req.dsAuthJwt; + } + next() + }) // Routes .get('/', commonControllers.indexController) - .get('/ds/login', (req, res, next) => {req.dsAuthCodeGrant.login(req, res, next)}) + .get('/ds/login', commonControllers.login) .get('/ds/callback', [dsLoginCB1, dsLoginCB2]) // OAuth callbacks. See below - .get('/ds/logout', (req, res) => {req.dsAuthCodeGrant.logout(req, res)}) - .get('/ds/logoutCallback', (req, res) => {req.dsAuthCodeGrant.logoutCallback(req, res)}) + .get('/ds/logout', commonControllers.logout) + .get('/ds/logoutCallback', commonControllers.logoutCallback) .get('/ds/mustAuthenticate', commonControllers.mustAuthenticateController) .get('/ds-return', commonControllers.returnController) .use(csrfProtection) // CSRF protection for the following routes @@ -131,6 +150,22 @@ let app = express() .post('/eg022', eg022.createController) .get('/eg023', eg023.getController) .post('/eg023', eg023.createController) + .get('/eg024', eg024.getController) + .post('/eg024', eg024.createController) + .get('/eg025', eg025.getController) + .post('/eg025', eg025.createController) + .get('/eg026', eg026.getController) + .post('/eg026', eg026.createController) + .get('/eg027', eg027.getController) + .post('/eg027', eg027.createController) + .get('/eg028', eg028.getController) + .post('/eg028', eg028.createController) + .get('/eg029', eg029.getController) + .post('/eg029', eg029.createController) + .get('/eg030', eg030.getController) + .post('/eg030', eg030.createController) + .get('/eg031', eg031.getController) + .post('/eg031', eg031.createController) ; function dsLoginCB1 (req, res, next) {req.dsAuthCodeGrant.oauth_callback1(req, res, next)} @@ -144,7 +179,7 @@ if (dsConfig.dsClientId && dsConfig.dsClientId !== '{CLIENT_ID}' && console.log(`Ready! Open ${hostUrl}`); } else { console.log(`PROBLEM: You need to set the clientId (Integrator Key), and perhaps other settings as well. -You can set them in the source file ds_configuration.js or set environment variables.\n`); +You can set them in the configuration file config/appsettings.json or set environment variables.\n`); process.exit(); // We're not using exit code of 1 to avoid extraneous npm messages. } @@ -187,7 +222,7 @@ let docusignStrategy = new DocusignStrategy({ * An additional OAuth query parameter is used to not allow silent authentication */ if (!dsConfig.allowSilentAuthentication) { - // See https://stackoverflow.com/a/32877712/64904 + // See https://stackoverflow.com/a/32877712/64904 docusignStrategy.authorizationParams = function(options) { return {prompt: 'login'}; } diff --git a/lib/DSAuthCodeGrant.js b/lib/DSAuthCodeGrant.js index 86dd62dc..0dc0cd83 100644 --- a/lib/DSAuthCodeGrant.js +++ b/lib/DSAuthCodeGrant.js @@ -1,11 +1,11 @@ -/** +/** * @file * This file implements the DSAuthCodeGrant class. * It handles the OAuth Authorization Code Grant flow. * It also looks up the user's default account and baseUrl - * + * * For the purposes of this example, it ignores the refresh - * token that is returned from DocuSign. In production, + * token that is returned from DocuSign. In production, * depending on your use case, you can store and then use the * refresh token instead of requiring the user to re-authenticate. * @author DocuSign @@ -14,7 +14,7 @@ 'use strict'; const moment = require('moment') - , dsConfig = require('../ds_configuration.js').config + , dsConfig = require('../config/index.js').config , passport = require('passport') , baseUriSuffix = '/restapi' , tokenReplaceMinGet = 60; // For a form Get, the token must expire at least this number of @@ -31,7 +31,7 @@ let DSAuthCodeGrant = function _DSAuthCodeGrant(req) { this._debug_prefix = 'DSAuthCodeGrant'; this._accessToken = req.user && req.user.accessToken; // The bearer token. Get it via #checkToken this._refreshToken = req.user && req.user.refreshToken; // Note, the refresh token is not used in this example. - // For production use, you'd want to store the refresh token in non-volatile storage since it is + // For production use, you'd want to store the refresh token in non-volatile storage since it is // good for 30 days. You'd probably want to encrypt it too. this._tokenExpiration = req.user && req.user.tokenExpirationTimestamp; // when does the token expire? this._debug = true; // ### DEBUG ### setting @@ -59,11 +59,12 @@ DSAuthCodeGrant.prototype.Error_invalid_grant = 'invalid_grant'; // message when DSAuthCodeGrant.prototype.login = function (req, res, next) { // Reset this.internalLogout(req, res); + req.session.authMethod = 'grand-auth'; passport.authenticate('docusign')(req, res, next); } DSAuthCodeGrant.prototype.oauth_callback1 = (req, res, next) => { - // This callback URL is used for the login flow + // This callback URL is used for the login flow passport.authenticate('docusign', { failureRedirect: '/ds/login' })(req, res, next) } DSAuthCodeGrant.prototype.oauth_callback2 = function _oauth_callback2(req, res, next) { @@ -86,17 +87,17 @@ DSAuthCodeGrant.prototype.oauth_callback2 = function _oauth_callback2(req, res, // The baseUri changes rarely so it can (and should) be cached. // // req.user holds the result of the DocuSign OAuth call and the OAuth::userInfo method, - // except for the expires element. + // except for the expires element. // req.user.accessToken: "eyJ0Xbz....vXXFw7IlVwfDRA" // req.user.accounts: An array of accounts that the user has access to // An example account: - // {account_id: "8118f2...8a", - // is_default: false, - // account_name: "Xylophone World", + // {account_id: "8118f2...8a", + // is_default: false, + // account_name: "Xylophone World", // base_uri: "https://demo.docusign.net"} (Note: does not include '/restapi/v2') // created: "2015-05-20T11:48:23.363" // when was the user's record created // email: "name@example.com" // the user's email - // The expires element is added in function _processDsResult in file index.js. + // The expires element is added in function _processDsResult in file index.js. // It is the datetime when the token will expire: // expires: Moment {_isAMomentObject: true, _isUTC: false, _pf: {…}, _locale: Locale, _d: Tue Jun 26 2018 04:05:37 GMT+0300 (IDT), …} // expiresIn: 28800 // when the token will expire, in seconds, from when the OAuth response is sent by DocuSign @@ -104,7 +105,7 @@ DSAuthCodeGrant.prototype.oauth_callback2 = function _oauth_callback2(req, res, // given_name: "Larry" // the user's first name // name: "Larry LastName" // provider: "docusign" - // refreshToken: "eyJ0eXAiOiJ...HB4Q" // Can be used to obtain a new set of access and response tokens. + // refreshToken: "eyJ0eXAiOiJ...HB4Q" // Can be used to obtain a new set of access and response tokens. // The lifetime for the refreshToken is typically 30 days // sub: "...5fed18870" // the user's id in guid format @@ -117,11 +118,11 @@ DSAuthCodeGrant.prototype.oauth_callback2 = function _oauth_callback2(req, res, let eg = req.session.eg; req.session.eg = null; res.redirect(`/${eg}`); - } else {res.redirect('/')} + } else {res.redirect('/')} } /** - * Clears the DocuSign authentication session token + * Clears the DocuSign authentication session token * https://account-d.docusign.com/oauth/logout * @function */ @@ -172,7 +173,7 @@ DSAuthCodeGrant.prototype.getDefaultAccountInfo = function _getDefaultAccountInf const targetAccountId = dsConfig.targetAccountId , accounts = req.user.accounts ; - + let account = null; // the account we want to use // Find the account... if (targetAccountId) { @@ -211,14 +212,14 @@ DSAuthCodeGrant.prototype.checkToken = function _checkToken(bufferMin = tokenRep if (this._debug) { if (noToken) {this._debug_log('checkToken: Starting up--need a token')} if (needToken && !noToken) {this._debug_log('checkToken: Replacing old token')} - //if (!needToken) {this._debug_log('checkToken: Using current token')} + if (!needToken) {this._debug_log('checkToken: Using current token')} } return (!needToken) } /** - * Store the example number in session storage so it will be + * Store the example number in session storage so it will be * used after the user is authenticated * @function * @param object req The request object diff --git a/lib/DSJwtAuth.js b/lib/DSJwtAuth.js new file mode 100644 index 00000000..96c10610 --- /dev/null +++ b/lib/DSJwtAuth.js @@ -0,0 +1,258 @@ +// dsJwtAuth.js + +/** + * @file + * This file handles the JWT authentication with DocuSign. + * It also looks up the user's account and base_url + * via the OAuth::userInfo method. + * See https://developers.docusign.com/esign-rest-api/guides/authentication/user-info-endpoints userInfo method. + * @author DocuSign + */ + + +'use strict'; +let DsJwtAuth = function _DsJwtAuth(req) { + // private globals + this._debug_prefix = 'DsJwtAuth'; + this.accessToken = req.user && req.user.accessToken; + this.accountId = req.user && req.user.accountId; + this.accountName = req.user && req.user.accountName; + this.basePath = req.user && req.user.basePath; + this._tokenExpiration = req.user && req.user.tokenExpirationTimestamp; + + // For production use, you'd want to store the refresh token in non-volatile storage since it is + // good for 30 days. You'd probably want to encrypt it too. + this._debug = true; // ### DEBUG ### setting + +}; +module.exports = DsJwtAuth; // SET EXPORTS for the module. + +const moment = require('moment') + , path = require('path') + , docusign = require('docusign-esign') + , dsConfig = require('../ds_configuration.js').config + , tokenReplaceMin = 10 // The accessToken must expire at least this number of + , tokenReplaceMinGet = 30; + +/** + * This is the key method for the object. + * It should be called before any API call to DocuSign. + * It checks that the existing access accessToken can be used. + * If the existing accessToken is expired or doesn't exist, then + * a new accessToken will be obtained from DocuSign by using + * the JWT flow. + * + * This is an async function so call it with await. + * + * SIDE EFFECT: Sets the access accessToken that the SDK will use. + * SIDE EFFECT: If the accountId et al is not set, then this method will + * also get the user's information + * @function + */ +DsJwtAuth.prototype.checkToken = function _checkToken(bufferMin = tokenReplaceMinGet) { + let noToken = !this.accessToken || !this._tokenExpiration + , now = moment() + , needToken = noToken || moment(this._tokenExpiration).subtract( + bufferMin, 'm').isBefore(now) + ; + if (this._debug) { + if (noToken) {this._debug_log('checkToken: Starting up--need a token')} + if (needToken && !noToken) {this._debug_log('checkToken: Replacing old token')} + if (!needToken) {this._debug_log('checkToken: Using current token')} + } + + return (!needToken) +} + +/** + * Async function to obtain a accessToken via JWT grant + * + * RETURNS {accessToken, tokenExpirationTimestamp} + * + * We need a new accessToken. We will use the DocuSign SDK's function. + */ +DsJwtAuth.prototype.getToken = async function _getToken() { + // Data used + // dsConfig.dsClientId + // dsConfig.impersonatedUserGuid + // dsConfig.privateKey + // dsConfig.authServer + const jwtLifeSec = 10 * 60, // requested lifetime for the JWT is 10 min + scopes = "signature", // impersonation scope is implied due to use of JWT grant + dsApi = new docusign.ApiClient(); + dsApi.setOAuthBasePath(dsConfig.authServer); + const results = await dsApi.requestJWTUserToken(dsConfig.dsClientId, + dsConfig.impersonatedUserGuid, scopes, dsConfig.privateKey, + jwtLifeSec); + const expiresAt = moment().add(results.body.expires_in, 's').subtract(tokenReplaceMin, 'm'); + this.accessToken = results.body.access_token; + this._tokenExpiration = expiresAt; + return { + accessToken: results.body.access_token, + tokenExpirationTimestamp: expiresAt + }; +} + +/** + * Sets the following variables: + * DsJwtAuth.accountId + * DsJwtAuth.accountName + * DsJwtAuth.basePath + * DsJwtAuth.userName + * DsJwtAuth.userEmail + * @function _getAccount + * @returns {promise} + * @promise + */ +DsJwtAuth.prototype.getUserInfo = async function _getUserInfo(){ + // Data used: + // dsConfig.targetAccountId + // dsConfig.authServer + // DsJwtAuth.accessToken + + const dsApi = new docusign.ApiClient() + , targetAccountId = dsConfig.targetAccountId + , baseUriSuffix = '/restapi'; + + dsApi.setOAuthBasePath(dsConfig.authServer); + const results = await dsApi.getUserInfo(this.accessToken); + + let accountInfo; + if (!Boolean(targetAccountId)) { + // find the default account + accountInfo = results.accounts.find(account => + account.isDefault === "true"); + } else { + // find the matching account + accountInfo = results.accounts.find(account => account.accountId == targetAccountId); + } + if (typeof accountInfo === 'undefined') { + throw new Error (`Target account ${targetAccountId} not found!`); + } + + this.accountId = accountInfo.accountId; + this.accountName = accountInfo.accountName; + this.basePath = accountInfo.baseUri + baseUriSuffix; + return { + accountId: this.accountId, + basePath: this.basePath, + accountName: this.accountName + } +} + + +/** + * Clears the accessToken. Same as logging out + * @function + */ +DsJwtAuth.prototype.clearToken = function(){ // "logout" function + this._tokenExpiration = false; + this.accessToken = false; +}; + +/** + * Store the example number in session storage so it will be + * used after the user is authenticated + * @function + * @param req {object} The request object + * @param eg {string} The example number that should be started after authentication + */ +DsJwtAuth.prototype.setEg = function _setEg(req, eg) { + req.session.eg = eg +} + +/** + * Login user + * @function + */ +DsJwtAuth.prototype.login = function (req, res, next) { + this.internalLogout(req, res); + req.session.authMethod = 'jwt-auth'; + const log = async () => { + const auth = await this.getToken(); + const user = await this.getUserInfo(); + req.session.accountId = user.accountId; + req.session.accountName = user.accountName; + req.session.basePath = user.basePath; + return { + ...auth, + ...user + }; + } + log() + .then(user => { + req.login(user, (err) => { + if (err) { return next(err); } + if (req.session.eg) { + let eg = req.session.eg; + req.session.eg = null; + res.redirect(`/${eg}`); + } else { + res.redirect('/') + } + }); + }) + .catch(e => { + let body = e.response && e.response.body; + if (body) { + // DocuSign API problem + if (body.error && body.error === 'consent_required') { + // Consent problem + let consent_scopes = "signature%20impersonation", + consent_url = `https://${dsConfig.authServer}/oauth/auth?response_type=code&` + + `scope=${consent_scopes}&client_id=${dsConfig.dsClientId}&` + + `redirect_uri=${dsConfig.appUrl}`; + res.redirect(consent_url); + } else { + // Some other DocuSign API problem + this._debug_log(`\nAPI problem: Status code ${e.response.status}, message body: + ${JSON.stringify(body, null, 4)}\n\n`); + } + } else { + // Not an API problem + throw e; + } + }); +} + +/** + * Clears the object's and session's user information including the tokens. + * @function + */ +DsJwtAuth.prototype.internalLogout = function _internalLogout(req, res) { + this._tokenExpiration = null; + req.session.accountId = null; + req.session.accountName = null; + req.session.basePath = null; +} + +/** + * Clears the user information including the tokens. + * @function + */ +DsJwtAuth.prototype.logoutCallback = function _logoutCallback (req, res) { + req.logout(); // see http://www.passportjs.org/docs/logout/ + this.internalLogout(req, res); + req.flash('info', 'You have logged out.'); + res.redirect('/'); +} + +/** + * Clears the DocuSign authentication session token + * https://account-d.docusign.com/oauth/logout + * @function + */ +DsJwtAuth.prototype.logout = function _logout (req, res) { + this.logoutCallback(req, res); +} + +/** + * If in debug mode, prints message to the console + * @function + * @param {string} m The message to be printed + * @private + */ +DsJwtAuth.prototype._debug_log = function(m){ + if (!this._debug) {return} + console.log(this._debug_prefix + ': ' + m) +} diff --git a/lib/commonControllers.js b/lib/commonControllers.js index f4f5456b..e36fe457 100644 --- a/lib/commonControllers.js +++ b/lib/commonControllers.js @@ -5,7 +5,7 @@ */ const fs = require('fs') - , dsConfig = require('../ds_configuration.js').config + , dsConfig = require('../config/appsettings.json') , documentationTopic = 'auth-code-grant-node' ; @@ -26,10 +26,28 @@ commonControllers.mustAuthenticateController = (req, res) => { res.render('pages/ds_must_authenticate', {title: "Authenticate with DocuSign"}); } +commonControllers.login = (req, res, next) => { + const { auth } = req.query; + if (auth === 'grand-auth') { + req.dsAuth = req.dsAuthCodeGrant; + } else if (auth === 'jwt-auth') { + req.dsAuth = req.dsAuthJwt; + } + req.dsAuth.login(req, res, next) +} + +commonControllers.logout = (req, res) => { + req.dsAuth.logout(req, res) +} + +commonControllers.logoutCallback = (req, res) => { + req.dsAuth.logoutCallback(req, res) +} + /** - * Display parameters after DS redirect to the application + * Display parameters after DS redirect to the application * after an embedded signing ceremony, etc - * @param {object} req Request object + * @param {object} req Request object * @param {object} res Result object */ commonControllers.returnController = (req, res) => { diff --git a/lib/examples/eg001EmbeddedSigning.js b/lib/examples/eg001EmbeddedSigning.js index 66e1cc99..4c3fe386 100644 --- a/lib/examples/eg001EmbeddedSigning.js +++ b/lib/examples/eg001EmbeddedSigning.js @@ -8,7 +8,7 @@ const path = require('path') , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg001EmbeddedSigning = exports @@ -18,29 +18,29 @@ const eg001EmbeddedSigning = exports , signerClientId = 1000 // The id of the signer within this application. , demoDocsPath = path.resolve(__dirname, '../../demo_documents') , pdf1File = 'World_Wide_Corp_lorem.pdf' - , dsReturnUrl = dsConfig.appUrl + '/ds-return' + , dsReturnUrl = dsConfig.appUrl + '/ds-return' , dsPingUrl = dsConfig.appUrl + '/' // Url that will be pinged by the DocuSign Signing Ceremony via Ajax ; /** * Create the envelope, the Signing Ceremony, and then redirect to the Signing Ceremony - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg001EmbeddedSigning.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -50,8 +50,8 @@ eg001EmbeddedSigning.createController = async (req, res) => { , signerEmail = validator.escape(body.signerEmail) , signerName = validator.escape(body.signerName) , envelopeArgs = { - signerEmail: signerEmail, - signerName: signerName, + signerEmail: signerEmail, + signerName: signerName, signerClientId: signerClientId, dsReturnUrl: dsReturnUrl, dsPingUrl: dsPingUrl @@ -74,7 +74,7 @@ eg001EmbeddedSigning.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -89,7 +89,7 @@ eg001EmbeddedSigning.createController = async (req, res) => { /** - * This function does the work of creating the envelope and the + * This function does the work of creating the envelope and the * embedded Signing Ceremony * @param {object} args */ @@ -135,8 +135,8 @@ eg001EmbeddedSigning.worker = async (args) => { */ function makeEnvelope(args){ // Data for this method - // args.signerEmail - // args.signerName + // args.signerEmail + // args.signerName // args.signerClientId // demoDocsPath (module constant) // pdf1File (module constant) @@ -145,74 +145,74 @@ function makeEnvelope(args){ // // The envelope has one recipients. // recipient 1 - signer - + let docPdfBytes; // read file from a local directory // The read could raise an exception if the file is not available! docPdfBytes = fs.readFileSync(path.resolve(demoDocsPath, pdf1File)); - + // create the envelope definition let env = new docusign.EnvelopeDefinition(); env.emailSubject = 'Please sign this document'; - + // add the documents let doc1 = new docusign.Document() , doc1b64 = Buffer.from(docPdfBytes).toString('base64') ; - + doc1.documentBase64 = doc1b64; doc1.name = 'Lorem Ipsum'; // can be different from actual file name doc1.fileExtension = 'pdf'; doc1.documentId = '3'; - + // The order in the docs array determines the order in the envelope env.documents = [doc1]; - + // Create a signer recipient to sign the document, identified by name and email // We set the clientUserId to enable embedded signing for the recipient // We're setting the parameters via the object creation let signer1 = docusign.Signer.constructFromObject({ email: args.signerEmail, - name: args.signerName, + name: args.signerName, clientUserId: args.signerClientId, - recipientId: 1 + recipientId: 1 }); - + // Create signHere fields (also known as tabs) on the documents, // We're using anchor (autoPlace) positioning // // The DocuSign platform seaches throughout your envelope's - // documents for matching anchor strings. + // documents for matching anchor strings. let signHere1 = docusign.SignHere.constructFromObject({ anchorString: '/sn1/', anchorYOffset: '10', anchorUnits: 'pixels', anchorXOffset: '20'}) ; - + // Tabs are set per recipient / signer let signer1Tabs = docusign.Tabs.constructFromObject({ signHereTabs: [signHere1]}); signer1.tabs = signer1Tabs; - + // Add the recipient to the envelope object let recipients = docusign.Recipients.constructFromObject({ signers: [signer1]}); env.recipients = recipients; - + // Request that the envelope be sent by setting |status| to "sent". // To request that the envelope be created as a draft, set to "created" env.status = 'sent'; - + return env; } function makeRecipientViewRequest(args) { // Data for this method - // args.dsReturnUrl - // args.signerEmail - // args.signerName + // args.dsReturnUrl + // args.signerEmail + // args.signerName // args.signerClientId - // args.dsPingUrl + // args.dsPingUrl let viewRequest = new docusign.RecipientViewRequest(); @@ -229,7 +229,7 @@ function makeRecipientViewRequest(args) { // authentication, you can include authenticate steps from DocuSign. // Eg, SMS authentication viewRequest.authenticationMethod = 'none'; - + // Recipient information must match embedded recipient info // we used to create the envelope. viewRequest.email = args.signerEmail; @@ -255,10 +255,11 @@ function makeRecipientViewRequest(args) { * Form page for this application */ eg001EmbeddedSigning.getController = (req, res) => { + console.log(req.dsAuth); // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg001EmbeddedSigning', { eg: eg, csrfToken: req.csrfToken(), @@ -270,7 +271,7 @@ eg001EmbeddedSigning.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg002SigningViaEmail.js b/lib/examples/eg002SigningViaEmail.js index d5b1b951..d34d436c 100644 --- a/lib/examples/eg002SigningViaEmail.js +++ b/lib/examples/eg002SigningViaEmail.js @@ -8,7 +8,7 @@ const path = require('path') , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg002SigningViaEmail = exports @@ -18,29 +18,27 @@ const eg002SigningViaEmail = exports , demoDocsPath = path.resolve(__dirname, '../../demo_documents') , doc2File = 'World_Wide_Corp_Battle_Plan_Trafalgar.docx' , doc3File = 'World_Wide_Corp_lorem.pdf' - , dsReturnUrl = dsConfig.appUrl + '/ds-return' - , dsPingUrl = dsConfig.appUrl + '/' // Url that will be pinged by the DocuSign Signing Ceremony via Ajax ; /** * Create the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg002SigningViaEmail.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -52,9 +50,9 @@ eg002SigningViaEmail.createController = async (req, res) => { , ccEmail = validator.escape(body.ccEmail) , ccName = validator.escape(body.ccName) , envelopeArgs = { - signerEmail: signerEmail, - signerName: signerName, - ccEmail: ccEmail, + signerEmail: signerEmail, + signerName: signerName, + ccEmail: ccEmail, ccName: ccName, status: "sent" } , args = { @@ -75,12 +73,12 @@ eg002SigningViaEmail.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // which need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -91,7 +89,7 @@ eg002SigningViaEmail.createController = async (req, res) => { } /** - * This function does the work of creating the envelope + * This function does the work of creating the envelope */ // ***DS.snippet.0.start eg002SigningViaEmail.worker = async (args) => { @@ -128,10 +126,10 @@ eg002SigningViaEmail.worker = async (args) => { */ function makeEnvelope(args){ // Data for this method - // args.signerEmail - // args.signerName - // args.ccEmail - // args.ccName + // args.signerEmail + // args.signerName + // args.ccEmail + // args.ccName // args.status // demoDocsPath (module constant) // doc2File (module constant) @@ -169,14 +167,14 @@ function makeEnvelope(args){ doc1.name = 'Order acknowledgement'; // can be different from actual file name doc1.fileExtension = 'html'; // Source data format. Signed docs are always pdf. doc1.documentId = '1'; // a label used to reference the doc - + // Alternate pattern: using constructors for docs 2 and 3... let doc2 = new docusign.Document.constructFromObject({ documentBase64: doc2b64, name: 'Battle Plan', // can be different from actual file name fileExtension: 'docx', documentId: '2'}); - + let doc3 = new docusign.Document.constructFromObject({ documentBase64: doc3b64, name: 'Lorem Ipsum', // can be different from actual file name @@ -250,10 +248,10 @@ function makeEnvelope(args){ function document1(args) { // Data for this method - // args.signerEmail - // args.signerName - // args.ccEmail - // args.ccName + // args.signerEmail + // args.signerName + // args.ccEmail + // args.ccName return ` @@ -288,7 +286,7 @@ eg002SigningViaEmail.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg002SigningViaEmail', { eg: eg, csrfToken: req.csrfToken(), @@ -300,7 +298,7 @@ eg002SigningViaEmail.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg003ListEnvelopes.js b/lib/examples/eg003ListEnvelopes.js index ad52f6ab..74b80b73 100644 --- a/lib/examples/eg003ListEnvelopes.js +++ b/lib/examples/eg003ListEnvelopes.js @@ -5,7 +5,7 @@ */ const docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config , moment = require('moment') , path = require('path') ; @@ -18,22 +18,22 @@ const eg003ListEnvelopes = exports /** * List envelopes in the user's account - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg003ListEnvelopes.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -55,7 +55,7 @@ eg003ListEnvelopes.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -79,7 +79,7 @@ eg003ListEnvelopes.worker = async (args) => { // args.accessToken // args.accountId - + let dsApiClient = new docusign.ApiClient(); dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); @@ -109,7 +109,7 @@ eg003ListEnvelopes.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg003ListEnvelopes', { eg: eg, csrfToken: req.csrfToken(), @@ -121,7 +121,7 @@ eg003ListEnvelopes.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg004EnvelopeInfo.js b/lib/examples/eg004EnvelopeInfo.js index e3771708..eba73b4e 100644 --- a/lib/examples/eg004EnvelopeInfo.js +++ b/lib/examples/eg004EnvelopeInfo.js @@ -6,7 +6,7 @@ const path = require('path') , docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg004EnvelopeInfo = exports @@ -18,27 +18,27 @@ const eg004EnvelopeInfo = exports /** * Get the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg004EnvelopeInfo.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } if (! req.session.envelopeId) { res.render('pages/examples/eg004EnvelopeInfo', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "Get envelope information", envelopeOk: req.session.envelopeId, sourceFile: path.basename(__filename), @@ -67,7 +67,7 @@ eg004EnvelopeInfo.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -115,7 +115,7 @@ eg004EnvelopeInfo.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg004EnvelopeInfo', { eg: eg, csrfToken: req.csrfToken(), @@ -128,7 +128,7 @@ eg004EnvelopeInfo.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } -} \ No newline at end of file +} diff --git a/lib/examples/eg005EnvelopeRecipients.js b/lib/examples/eg005EnvelopeRecipients.js index 3f33b6fb..0542d4f4 100644 --- a/lib/examples/eg005EnvelopeRecipients.js +++ b/lib/examples/eg005EnvelopeRecipients.js @@ -6,7 +6,7 @@ const path = require('path') , docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg005EnvelopeRecipients = exports @@ -18,27 +18,27 @@ const eg005EnvelopeRecipients = exports /** * List the envelope recipients - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg005EnvelopeRecipients.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } if (! req.session.envelopeId) { res.render('pages/examples/eg005EnvelopeRecipients', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "List envelope recipients", envelopeOk: req.session.envelopeId, sourceFile: path.basename(__filename), @@ -67,7 +67,7 @@ eg005EnvelopeRecipients.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -115,7 +115,7 @@ eg005EnvelopeRecipients.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg005EnvelopeRecipients', { eg: eg, csrfToken: req.csrfToken(), @@ -128,7 +128,7 @@ eg005EnvelopeRecipients.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg006EnvelopeDocs.js b/lib/examples/eg006EnvelopeDocs.js index ace58da3..2ec02fe4 100644 --- a/lib/examples/eg006EnvelopeDocs.js +++ b/lib/examples/eg006EnvelopeDocs.js @@ -6,7 +6,7 @@ const path = require('path') , docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg006EnvelopeDocs = exports @@ -18,27 +18,27 @@ const eg006EnvelopeDocs = exports /** * Get the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg006EnvelopeDocs.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } if (! req.session.envelopeId) { res.render('pages/examples/eg006EnvelopeDocs', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "List envelope documents", envelopeOk: req.session.envelopeId, sourceFile: path.basename(__filename), @@ -66,7 +66,7 @@ eg006EnvelopeDocs.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -79,8 +79,8 @@ eg006EnvelopeDocs.createController = async (req, res) => { {name: 'Zip archive', type: 'zip' , documentId: 'archive'}] // The certificate of completion is named "summary". // We give it a better name below. - , envelopeDocItems = results.envelopeDocuments.map( doc => - ({documentId: doc.documentId, + , envelopeDocItems = results.envelopeDocuments.map( doc => + ({documentId: doc.documentId, name: doc.documentId === "certificate" ? "Certificate of completion" : doc.name, type: doc.type}) ) @@ -110,7 +110,7 @@ eg006EnvelopeDocs.worker = async (args) => { // args.accountId // args.envelopeId - + let dsApiClient = new docusign.ApiClient(); dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); @@ -131,7 +131,7 @@ eg006EnvelopeDocs.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg006EnvelopeDocs', { eg: eg, csrfToken: req.csrfToken(), @@ -144,7 +144,7 @@ eg006EnvelopeDocs.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } -} \ No newline at end of file +} diff --git a/lib/examples/eg007EnvelopeGetDoc.js b/lib/examples/eg007EnvelopeGetDoc.js index d076e194..0db67376 100644 --- a/lib/examples/eg007EnvelopeGetDoc.js +++ b/lib/examples/eg007EnvelopeGetDoc.js @@ -6,7 +6,7 @@ const path = require('path') , docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config , validator = require('validator') ; @@ -18,28 +18,28 @@ const eg007EnvelopeGetDoc = exports /** * Get the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg007EnvelopeGetDoc.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } let envelopeDocuments = req.session.envelopeDocuments; if (! req.session.envelopeId || ! envelopeDocuments ) { res.render('pages/examples/eg007EnvelopeGetDoc', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "Download a document", envelopeOk: req.session.envelopeId, documentsOk: envelopeDocuments, @@ -72,7 +72,7 @@ eg007EnvelopeGetDoc.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -130,7 +130,7 @@ eg007EnvelopeGetDoc.worker = async (args) => { // Return the file information // See https://stackoverflow.com/a/30625085/64904 let mimetype; - if (pdfFile) { + if (pdfFile) { mimetype = 'application/pdf' } else if (docItem.type === 'zip') { mimetype = 'application/zip' @@ -150,7 +150,7 @@ eg007EnvelopeGetDoc.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { let envelopeDocuments = req.session.envelopeDocuments, documentOptions; @@ -172,7 +172,7 @@ eg007EnvelopeGetDoc.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg008CreateTemplate.js b/lib/examples/eg008CreateTemplate.js index 5c3255ac..f7776056 100644 --- a/lib/examples/eg008CreateTemplate.js +++ b/lib/examples/eg008CreateTemplate.js @@ -6,7 +6,7 @@ const path = require('path') , docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config , fs = require('fs-extra') ; @@ -21,22 +21,22 @@ const eg008CreateTemplate = exports /** * Create a template - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg008CreateTemplate.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -58,14 +58,14 @@ eg008CreateTemplate.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { // Save the templateId in the session so they can be used in future examples req.session.templateId = results.templateId; - let msg = results.createdNewTemplate ? + let msg = results.createdNewTemplate ? "The template has been created!" : "Done. The template already existed in your account."; @@ -76,7 +76,7 @@ eg008CreateTemplate.createController = async (req, res) => { }); } } - + /** * This function does the work of checking to see if the template exists and creating it if not. */ @@ -98,12 +98,12 @@ eg008CreateTemplate.createController = async (req, res) => { , resultsTemplateName = null , createdNewTemplate = null ; - + // Step 1. See if the template already exists // Exceptions will be caught by the calling function results = await templatesApi.listTemplates( args.accountId, {searchText: args.templateName}); - + if (results.resultSetSize > 0) { templateId = results.envelopeTemplates[0].templateId; resultsTemplateName = results.envelopeTemplates[0].name; @@ -120,12 +120,12 @@ eg008CreateTemplate.createController = async (req, res) => { args.accountId, {searchText: args.templateName}); templateId = results.envelopeTemplates[0].templateId; resultsTemplateName = results.envelopeTemplates[0].name; - + } return ({ templateId: templateId, - templateName: resultsTemplateName, + templateName: resultsTemplateName, createdNewTemplate: createdNewTemplate} ) } @@ -189,7 +189,7 @@ function makeTemplate(){ tabLabel: "ckAuthorization"}) , check2 = docusign.Checkbox.constructFromObject({ documentId: "1", pageNumber: "1", xPosition: "75", yPosition: "447", - tabLabel: "ckAuthentication"}) + tabLabel: "ckAuthentication"}) , check3 = docusign.Checkbox.constructFromObject({ documentId: "1", pageNumber: "1", xPosition: "75", yPosition: "478", tabLabel: "ckAgreement"}) @@ -199,8 +199,8 @@ function makeTemplate(){ , list1 = docusign.List.constructFromObject({ documentId: "1", pageNumber: "1", xPosition: "142", yPosition: "291", font: "helvetica", fontSize: "size14", tabLabel: "list", - required: "false", - listItems: [ + required: "false", + listItems: [ docusign.ListItem.constructFromObject({text: "Red", value: "red" }), docusign.ListItem.constructFromObject({text: "Orange", value: "orange"}), docusign.ListItem.constructFromObject({text: "Yellow", value: "yellow"}), @@ -267,7 +267,7 @@ function makeTemplate(){ recipients: recipients, status: "created" }); - + return template; } // ***DS.snippet.0.end @@ -280,7 +280,7 @@ eg008CreateTemplate.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg008CreateTemplate', { eg: eg, csrfToken: req.csrfToken(), @@ -292,7 +292,7 @@ eg008CreateTemplate.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg009UseTemplate.js b/lib/examples/eg009UseTemplate.js index 622db4ce..1f307604 100644 --- a/lib/examples/eg009UseTemplate.js +++ b/lib/examples/eg009UseTemplate.js @@ -7,7 +7,7 @@ const path = require('path') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg009UseTemplate = exports @@ -19,28 +19,28 @@ const eg009UseTemplate = exports /** * Send envelope with a template - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg009UseTemplate.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } if (!req.session.templateId) { res.render('pages/examples/eg009UseTemplate', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "Send envelope using a template", templateOk: req.session.templateId, sourceFile: path.basename(__filename), @@ -59,9 +59,9 @@ eg009UseTemplate.createController = async (req, res) => { , ccName = validator.escape(body.ccName) , envelopeArgs = { templateId: req.session.templateId, - signerEmail: signerEmail, - signerName: signerName, - ccEmail: ccEmail, + signerEmail: signerEmail, + signerName: signerName, + ccEmail: ccEmail, ccName: ccName } , args = { accessToken: req.user.accessToken, @@ -81,12 +81,12 @@ eg009UseTemplate.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // which need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -97,8 +97,8 @@ eg009UseTemplate.createController = async (req, res) => { } /** - * This function does the work of creating the envelope - * @param {object} args object + * This function does the work of creating the envelope + * @param {object} args object */ // ***DS.snippet.0.start eg009UseTemplate.worker = async (args) => { @@ -112,7 +112,7 @@ eg009UseTemplate.worker = async (args) => { dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); let envelopesApi = new docusign.EnvelopesApi(dsApiClient); - + // Step 1. Make the envelope request body let envelope = makeEnvelope(args.envelopeArgs) @@ -133,10 +133,10 @@ eg009UseTemplate.worker = async (args) => { */ function makeEnvelope(args){ // Data for this method - // args.signerEmail - // args.signerName - // args.ccEmail - // args.ccName + // args.signerEmail + // args.signerName + // args.ccEmail + // args.ccName // args.templateId @@ -178,7 +178,7 @@ eg009UseTemplate.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg009UseTemplate', { eg: eg, csrfToken: req.csrfToken(), @@ -191,7 +191,7 @@ eg009UseTemplate.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } -} \ No newline at end of file +} diff --git a/lib/examples/eg010SendBinaryDocs.js b/lib/examples/eg010SendBinaryDocs.js index 5e0dc926..11d16b5a 100644 --- a/lib/examples/eg010SendBinaryDocs.js +++ b/lib/examples/eg010SendBinaryDocs.js @@ -1,12 +1,12 @@ /** * @file - * Example 010: Send envelope with multipart mime + * Example 010: Send envelope with multipart mime * @author DocuSign */ const path = require('path') , fs = require('fs-extra') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config , rp = require('request-promise-native') , validator = require('validator') ; @@ -22,23 +22,23 @@ const eg010SendBinaryDocs = exports /** - * Create envelope using multipart and sending documents in binary - * @param {object} req Request obj + * Create envelope using multipart and sending documents in binary + * @param {object} req Request obj * @param {object} res Response obj */ eg010SendBinaryDocs.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -50,16 +50,16 @@ eg010SendBinaryDocs.createController = async (req, res) => { , ccEmail = validator.escape(body.ccEmail) , ccName = validator.escape(body.ccName) , envelopeArgs = { - signerEmail: signerEmail, - signerName: signerName, - ccEmail: ccEmail, + signerEmail: signerEmail, + signerName: signerName, + ccEmail: ccEmail, ccName: ccName } , args = { accessToken: req.user.accessToken, basePath: req.session.basePath, accountId: req.session.accountId, envelopeArgs: envelopeArgs, - demoDocsPath: demoDocsPath, + demoDocsPath: demoDocsPath, doc2File: doc2File, doc3File: doc3File } @@ -81,12 +81,12 @@ eg010SendBinaryDocs.createController = async (req, res) => { let errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // which need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -107,28 +107,28 @@ eg010SendBinaryDocs.worker = async (args) => { // args.basePath // args.accessToken // args.accountId - // demoDocsPath: relative path for the demo docs + // demoDocsPath: relative path for the demo docs // doc2File: file name for doc 2 // doc3File: file name for doc 3 - + // Step 1. Make the envelope JSON request body let envelopeJSON = makeEnvelopeJSON( args.envelopeArgs ) , results = null ; - + // Step 2. Gather documents and their headers // Read files from a local directory // The reads could raise an exception if the file is not available! let documents = [ - {mime: "text/html", filename: envelopeJSON.documents[0].name, + {mime: "text/html", filename: envelopeJSON.documents[0].name, documentId: envelopeJSON.documents[0].documentId, bytes: document1(args.envelopeArgs)}, - {mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - filename: envelopeJSON.documents[1].name, + {mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + filename: envelopeJSON.documents[1].name, documentId: envelopeJSON.documents[1].documentId, bytes: fs.readFileSync(path.resolve(args.demoDocsPath, args.doc2File))}, - {mime: "application/pdf", filename: envelopeJSON.documents[2].name, + {mime: "application/pdf", filename: envelopeJSON.documents[2].name, documentId: envelopeJSON.documents[2].documentId, bytes: fs.readFileSync(path.resolve(args.demoDocsPath, args.doc3File))} ]; @@ -136,12 +136,12 @@ eg010SendBinaryDocs.worker = async (args) => { // Step 3. Create the multipart body let CRLF = "\r\n" , boundary = "multipartboundary_multipartboundary" - , hyphens = "--" + , hyphens = "--" , reqBody ; reqBody = Buffer.from([ - hyphens, boundary, + hyphens, boundary, CRLF, "Content-Type: application/json", CRLF, "Content-Disposition: form-data", CRLF, @@ -160,16 +160,16 @@ eg010SendBinaryDocs.worker = async (args) => { ) }) // Add closing boundary - reqBody = Buffer.concat([reqBody, + reqBody = Buffer.concat([reqBody, Buffer.from([CRLF, hyphens, boundary, hyphens, CRLF].join(''))]); - + let options = { method: 'POST', uri: `${args.basePath}/v2/accounts/${args.accountId}/envelopes`, auth: {bearer: args.accessToken}, headers: { Accept: 'application/json', - 'Content-Type': + 'Content-Type': `multipart/form-data; boundary=${boundary}` }, body: reqBody @@ -199,10 +199,10 @@ eg010SendBinaryDocs.worker = async (args) => { */ function makeEnvelopeJSON(args){ // Data for this method - // args.signerEmail - // args.signerName - // args.ccEmail - // args.ccName + // args.signerEmail + // args.signerName + // args.ccEmail + // args.ccName // document 1 (html) has tag **signature_1** // document 2 (docx) has tag /sn1/ @@ -297,10 +297,10 @@ function makeEnvelopeJSON(args){ */ function document1(args) { // Data for this method - // args.signerEmail - // args.signerName - // args.ccEmail - // args.ccName + // args.signerEmail + // args.signerName + // args.ccEmail + // args.ccName return ` @@ -336,7 +336,7 @@ eg010SendBinaryDocs.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg010SendBinaryDocs', { eg: eg, csrfToken: req.csrfToken(), @@ -348,7 +348,7 @@ eg010SendBinaryDocs.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg011EmbeddedSending.js b/lib/examples/eg011EmbeddedSending.js index 514c4a20..b3980fce 100644 --- a/lib/examples/eg011EmbeddedSending.js +++ b/lib/examples/eg011EmbeddedSending.js @@ -5,10 +5,9 @@ */ const path = require('path') - , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config , eg002 = require('./eg002SigningViaEmail') // used to create envelope ; @@ -16,30 +15,27 @@ const eg011EmbeddedSending = exports , eg = 'eg011' // This example reference. , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 - , demoDocsPath = path.resolve(__dirname, '../../demo_documents') - , doc2File = 'World_Wide_Corp_Battle_Plan_Trafalgar.docx' - , doc3File = 'World_Wide_Corp_lorem.pdf' - , dsReturnUrl = dsConfig.appUrl + '/ds-return' + , dsReturnUrl = dsConfig.appUrl + '/ds-return' ; /** * Create the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg011EmbeddedSending.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -52,9 +48,9 @@ eg011EmbeddedSending.createController = async (req, res) => { , ccName = validator.escape(body.ccName) , startingView = validator.escape(body.startingView) , envelopeArgs = { - signerEmail: signerEmail, - signerName: signerName, - ccEmail: ccEmail, + signerEmail: signerEmail, + signerName: signerName, + ccEmail: ccEmail, ccName: ccName, dsReturnUrl: dsReturnUrl, } @@ -77,7 +73,7 @@ eg011EmbeddedSending.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -91,7 +87,7 @@ eg011EmbeddedSending.createController = async (req, res) => { } /** - * This function does the work of creating the envelope in + * This function does the work of creating the envelope in * draft mode and returning a URL for the sender's view * @param {object} args object */ @@ -102,13 +98,13 @@ eg011EmbeddedSending.worker = async (args) => { // args.accessToken // args.accountId // args.startingView -- 'recipient' or 'tagging' - + let dsApiClient = new docusign.ApiClient(); dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); let envelopesApi = new docusign.EnvelopesApi(dsApiClient); - // Step 1. Make the envelope with "created" (draft) status + // Step 1. Make the envelope with "created" (draft) status args.envelopeArgs.status = "created"; // We want a draft envelope let results = await eg002.worker(args) , envelopeId = results.envelopeId; @@ -120,7 +116,7 @@ eg011EmbeddedSending.worker = async (args) => { results = await envelopesApi.createSenderView( args.accountId, envelopeId, {returnUrlRequest: viewRequest}); - + // Switch to Recipient and Documents view if requested by the user let url = results.url; console.log (`startingView: ${args.startingView}`); @@ -151,7 +147,7 @@ eg011EmbeddedSending.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg011EmbeddedSending', { eg: eg, csrfToken: req.csrfToken(), @@ -163,7 +159,7 @@ eg011EmbeddedSending.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg012EmbeddedConsole.js b/lib/examples/eg012EmbeddedConsole.js index 94c29589..386ea7ba 100644 --- a/lib/examples/eg012EmbeddedConsole.js +++ b/lib/examples/eg012EmbeddedConsole.js @@ -5,37 +5,36 @@ */ const path = require('path') - , fs = require('fs-extra') , validator = require('validator') , docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg012EmbeddedConsole = exports , eg = 'eg012' // This example reference. , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 - , dsReturnUrl = dsConfig.appUrl + '/ds-return' + , dsReturnUrl = dsConfig.appUrl + '/ds-return' ; /** * The controller - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg012EmbeddedConsole.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -63,7 +62,7 @@ eg012EmbeddedConsole.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -113,8 +112,8 @@ function makeConsoleViewRequest(args) { // args.envelopeId let viewRequest = new docusign.ConsoleViewRequest(); - // Set the url where you want the recipient to go once they are done - // with the NDSE. It is usually the case that the + // Set the url where you want the recipient to go once they are done + // with the NDSE. It is usually the case that the // user will never "finish" with the NDSE. // Assume that control will not be passed back to your app. viewRequest.returnUrl = args.dsReturnUrl; @@ -133,7 +132,7 @@ eg012EmbeddedConsole.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg012EmbeddedConsole', { eg: eg, csrfToken: req.csrfToken(), @@ -146,7 +145,7 @@ eg012EmbeddedConsole.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg013AddDocToTemplate.js b/lib/examples/eg013AddDocToTemplate.js index e2c308e2..8c835368 100644 --- a/lib/examples/eg013AddDocToTemplate.js +++ b/lib/examples/eg013AddDocToTemplate.js @@ -5,10 +5,9 @@ */ const path = require('path') - , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg013AddDocToTemplate = exports @@ -16,36 +15,35 @@ const eg013AddDocToTemplate = exports , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 , signerClientId = 1000 // The id of the signer within this application. - , demoDocsPath = path.resolve(__dirname, '../../demo_documents') - , dsReturnUrl = dsConfig.appUrl + '/ds-return' + , dsReturnUrl = dsConfig.appUrl + '/ds-return' , dsPingUrl = dsConfig.appUrl + '/' // Url that will be pinged by the DocuSign Signing Ceremony via Ajax ; /** * Create the envelope, the Signing Ceremony, and then redirect to the Signing Ceremony - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg013AddDocToTemplate.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } if (!req.session.templateId) { res.render('pages/examples/eg013AddDocToTemplate', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "Embedded Signing Ceremony from template and extra doc", templateOk: req.session.templateId, sourceFile: path.basename(__filename), @@ -67,12 +65,12 @@ eg013AddDocToTemplate.createController = async (req, res) => { , envelopeArgs = { templateId: req.session.templateId, - signerEmail: signerEmail, - signerName: signerName, + signerEmail: signerEmail, + signerName: signerName, signerClientId: signerClientId, ccEmail: ccEmail, ccName: ccName, - item: item, + item: item, quantity: quantity, dsReturnUrl: dsReturnUrl, dsPingUrl: dsPingUrl @@ -95,7 +93,7 @@ eg013AddDocToTemplate.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -109,7 +107,7 @@ eg013AddDocToTemplate.createController = async (req, res) => { } /** - * This function does the work of creating the envelope and the + * This function does the work of creating the envelope and the * embedded Signing Ceremony * @param {object} args object */ @@ -132,7 +130,7 @@ eg013AddDocToTemplate.worker = async (args) => { // Exceptions will be caught by the calling function let results = await envelopesApi.createEnvelope( args.accountId, {envelopeDefinition: envelope}); - + let envelopeId = results.envelopeId; console.log(`Envelope was created. EnvelopeId ${envelopeId}`); @@ -155,35 +153,35 @@ eg013AddDocToTemplate.worker = async (args) => { */ function makeEnvelope(args){ // Data for this method - // args.signerEmail - // args.signerName + // args.signerEmail + // args.signerName // args.signerClientId - // args.ccEmail - // args.ccName + // args.ccEmail + // args.ccName // args.templateId - // The envelope request object uses Composite Template to + // The envelope request object uses Composite Template to // include in the envelope: // 1. A template stored on the DocuSign service - // 2. An additional document which is a custom HTML source document - + // 2. An additional document which is a custom HTML source document + // Create Recipients for server template. Note that Recipients object // is used, not TemplateRole // // Create a signer recipient for the signer role of the server template let signer1 = docusign.Signer.constructFromObject({ email: args.signerEmail, - name: args.signerName, + name: args.signerName, roleName: "signer", recipientId: "1", // Adding clientUserId transforms the template recipient // into an embedded recipient: - clientUserId: args.signerClientId + clientUserId: args.signerClientId }); // Create the cc recipient let cc1 = docusign.CarbonCopy.constructFromObject({ email: args.ccEmail, - name: args.ccName, + name: args.ccName, roleName: "cc", recipientId: "2" }); @@ -197,7 +195,7 @@ function makeEnvelope(args){ serverTemplates: [ docusign.ServerTemplate.constructFromObject({ sequence: "1", - templateId: args.templateId + templateId: args.templateId }) ], // Add the roles via an inlineTemplate @@ -272,12 +270,12 @@ function makeEnvelope(args){ function document1(args) { // Data for this method - // args.signerEmail - // args.signerName - // args.ccEmail - // args.ccName - // args.item - // args.quantity + // args.signerEmail + // args.signerName + // args.ccEmail + // args.ccName + // args.item + // args.quantity return ` @@ -309,8 +307,8 @@ function document1(args) { function makeRecipientViewRequest(args) { // Data for this method // args.dsReturnUrl - // args.signerEmail - // args.signerName + // args.signerEmail + // args.signerName // args.signerClientId // args.dsPingUrl @@ -325,7 +323,7 @@ function makeRecipientViewRequest(args) { // authentication, you can include authenticate steps from DocuSign. // Eg, SMS authentication viewRequest.authenticationMethod = 'none'; - + // Recipient information must match embedded recipient info // we used to create the envelope. viewRequest.email = args.signerEmail; @@ -353,7 +351,7 @@ eg013AddDocToTemplate.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg013AddDocToTemplate', { eg: eg, csrfToken: req.csrfToken(), @@ -366,7 +364,7 @@ eg013AddDocToTemplate.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg014CollectPayment.js b/lib/examples/eg014CollectPayment.js index d20fba61..7d8136d1 100644 --- a/lib/examples/eg014CollectPayment.js +++ b/lib/examples/eg014CollectPayment.js @@ -8,7 +8,7 @@ const path = require('path') , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg014CollectPayment = exports @@ -22,22 +22,22 @@ const eg014CollectPayment = exports /** * Create the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg014CollectPayment.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -49,9 +49,9 @@ eg014CollectPayment.createController = async (req, res) => { , ccEmail = validator.escape(body.ccEmail) , ccName = validator.escape(body.ccName) , envelopeArgs = { - signerEmail: signerEmail, - signerName: signerName, - ccEmail: ccEmail, + signerEmail: signerEmail, + signerName: signerName, + ccEmail: ccEmail, ccName: ccName, status: "sent", gatewayAccountId: dsConfig.gatewayAccountId, @@ -76,12 +76,12 @@ eg014CollectPayment.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // which need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -92,7 +92,7 @@ eg014CollectPayment.createController = async (req, res) => { } /** - * This function does the work of creating the envelope + * This function does the work of creating the envelope * @param {object} args object */ // ***DS.snippet.0.start @@ -130,10 +130,10 @@ eg014CollectPayment.worker = async (args) => { */ function makeEnvelope(args){ // Data for this method - // args.signerEmail - // args.signerName - // args.ccEmail - // args.ccName + // args.signerEmail + // args.signerName + // args.ccEmail + // args.ccName // args.status // args.gatewayAccountId // args.gatewayName @@ -141,10 +141,10 @@ function makeEnvelope(args){ // demoDocsPath -- module global // doc1File -- module global - + // document 1 (html) has multiple tags: // /l1q/ and /l2q/ -- quantities: drop down - // /l1e/ and /l2e/ -- extended: payment lines + // /l1e/ and /l2e/ -- extended: payment lines // /l3t/ -- total -- formula // // The envelope has two recipients. @@ -170,8 +170,8 @@ function makeEnvelope(args){ , l2Name = "Xylophone" , l2Price = 150 , l2Description = `$${l2Price} each` - , currencyMultiplier = 100 - ; + , currencyMultiplier = 100 + ; // read file from a local directory // The read could raise an exception if the file is not available! @@ -225,7 +225,7 @@ function makeEnvelope(args){ anchorString: '/sn1/', anchorYOffset: '10', anchorUnits: 'pixels', anchorXOffset: '20'}) - + , listItem0 = docusign.ListItem.constructFromObject({ text: "none", value: "0"}) , listItem1 = docusign.ListItem.constructFromObject({ @@ -248,7 +248,7 @@ function makeEnvelope(args){ text: "9", value: "9"}) , listItem10 = docusign.ListItem.constructFromObject({ text: "10", value: "10"}) - + , listl1q = docusign.List.constructFromObject({ font: "helvetica", fontSize: "size11", @@ -286,7 +286,7 @@ function makeEnvelope(args){ required: "true", locked: "true", disableAutoSize: "false", - }) + }) , formulal2e = docusign.FormulaTab.constructFromObject({ font: "helvetica", fontSize: "size11", @@ -299,8 +299,8 @@ function makeEnvelope(args){ required: "true", locked: "true", disableAutoSize: "false", - }) - // Formula for the total + }) + // Formula for the total , formulal3t = docusign.FormulaTab.constructFromObject({ font: "helvetica", bold: "true", @@ -342,7 +342,7 @@ function makeEnvelope(args){ pageNumber: "1", xPosition: "0", yPosition: "0" - }) + }) ; // Tabs are set per recipient / signer @@ -375,7 +375,7 @@ eg014CollectPayment.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg014CollectPayment', { eg: eg, csrfToken: req.csrfToken(), @@ -388,7 +388,7 @@ eg014CollectPayment.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg015EnvelopeTabData.js b/lib/examples/eg015EnvelopeTabData.js index d792d922..5f8c7614 100644 --- a/lib/examples/eg015EnvelopeTabData.js +++ b/lib/examples/eg015EnvelopeTabData.js @@ -6,7 +6,7 @@ const path = require('path') , docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg015EnvelopeTabData = exports @@ -18,27 +18,27 @@ const eg015EnvelopeTabData = exports /** * Get the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg015EnvelopeTabData.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } if (! req.session.envelopeId) { res.render('pages/examples/eg015EnvelopeTabData', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "Get envelope tab data", envelopeOk: req.session.envelopeId, sourceFile: path.basename(__filename), @@ -67,7 +67,7 @@ eg015EnvelopeTabData.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -114,7 +114,7 @@ eg015EnvelopeTabData.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg015EnvelopeTabData', { eg: eg, csrfToken: req.csrfToken(), @@ -127,7 +127,7 @@ eg015EnvelopeTabData.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } -} \ No newline at end of file +} diff --git a/lib/examples/eg016SetTabValues.js b/lib/examples/eg016SetTabValues.js index fed51521..bf745fe4 100644 --- a/lib/examples/eg016SetTabValues.js +++ b/lib/examples/eg016SetTabValues.js @@ -8,7 +8,7 @@ const path = require('path') , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg016SetTabValues = exports @@ -16,28 +16,28 @@ const eg016SetTabValues = exports , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 , signerClientId = 1000 // The id of the signer within this application. - , dsReturnUrl = dsConfig.appUrl + '/ds-return' + , dsReturnUrl = dsConfig.appUrl + '/ds-return' ; /** * Create the envelope, the Signing Ceremony, and then redirect to the Signing Ceremony - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg016SetTabValues.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } @@ -47,8 +47,8 @@ eg016SetTabValues.createController = async (req, res) => { , signerEmail = validator.escape(body.signerEmail) , signerName = validator.escape(body.signerName) , envelopeArgs = { - signerEmail: signerEmail, - signerName: signerName, + signerEmail: signerEmail, + signerName: signerName, signerClientId: signerClientId, dsReturnUrl: dsReturnUrl } @@ -70,7 +70,7 @@ eg016SetTabValues.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -87,7 +87,7 @@ eg016SetTabValues.createController = async (req, res) => { /** - * This function does the work of creating the envelope and the + * This function does the work of creating the envelope and the * embedded Signing Ceremony * @param {object} args */ @@ -97,8 +97,8 @@ eg016SetTabValues.worker = async (args) => { // args.basePath // args.accessToken // args.accountId - // args.envelopeArgs.signerEmail - // args.envelopeArgs.signerName + // args.envelopeArgs.signerEmail + // args.envelopeArgs.signerName // args.envelopeArgs.signerClientId // args.envelopeArgs.dsReturnUrl @@ -144,8 +144,8 @@ eg016SetTabValues.worker = async (args) => { */ function makeEnvelope(args){ // Data for this method - // args.signerEmail - // args.signerName + // args.signerEmail + // args.signerName // args.signerClientId @@ -182,9 +182,9 @@ function makeEnvelope(args){ // We set the clientUserId to enable embedded signing for the recipient , signer = docusign.Signer.constructFromObject({ email: args.signerEmail, - name: args.signerName, + name: args.signerName, clientUserId: args.signerClientId, - recipientId: 1 + recipientId: 1 }) // Create signHere field (also known as tabs) on the document, , signHere = docusign.SignHere.constructFromObject({ @@ -211,7 +211,7 @@ function makeEnvelope(args){ }) // Create the salary field. It should be human readable, so // add a comma before the thousands number, a currency indicator, etc. - , usFormat = new Intl.NumberFormat('en-US', + , usFormat = new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD', minimumFractionDigits: 0}) , salaryReadable = usFormat.format(salary) , textSalary = docusign.Text.constructFromObject({ @@ -265,7 +265,7 @@ eg016SetTabValues.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg016SetTabValues', { eg: eg, csrfToken: req.csrfToken(), @@ -277,7 +277,7 @@ eg016SetTabValues.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg017SetTemplateTabValues.js b/lib/examples/eg017SetTemplateTabValues.js index ea678305..a525d657 100644 --- a/lib/examples/eg017SetTemplateTabValues.js +++ b/lib/examples/eg017SetTemplateTabValues.js @@ -7,7 +7,7 @@ const path = require('path') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg017SetTemplateTabValues = exports @@ -19,28 +19,28 @@ const eg017SetTemplateTabValues = exports /** * Send envelope with a template - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg017SetTemplateTabValues.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } if (!req.session.templateId) { res.render('pages/examples/eg017SetTemplateTabValues', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "Send envelope using a template", templateOk: req.session.templateId, sourceFile: path.basename(__filename), @@ -59,12 +59,12 @@ eg017SetTemplateTabValues.createController = async (req, res) => { , ccName = validator.escape(body.ccName) , envelopeArgs = { templateId: req.session.templateId, - signerEmail: signerEmail, + signerEmail: signerEmail, signerName: signerName, signerClientId: 1000, - ccEmail: ccEmail, + ccEmail: ccEmail, ccName: ccName, - dsReturnUrl: dsConfig.appUrl + '/ds-return' + dsReturnUrl: dsConfig.appUrl + '/ds-return' } , args = { accessToken: req.user.accessToken, @@ -84,7 +84,7 @@ eg017SetTemplateTabValues.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -100,8 +100,8 @@ eg017SetTemplateTabValues.createController = async (req, res) => { } /** - * This function does the work of creating the envelope - * @param {object} args + * This function does the work of creating the envelope + * @param {object} args */ // ***DS.snippet.0.start eg017SetTemplateTabValues.worker = async (args) => { @@ -109,8 +109,8 @@ eg017SetTemplateTabValues.worker = async (args) => { // args.basePath // args.accessToken // args.accountId - // args.envelopeArgs.signerEmail - // args.envelopeArgs.signerName + // args.envelopeArgs.signerEmail + // args.envelopeArgs.signerName // args.envelopeArgs.signerClientId // args.envelopeArgs.dsReturnUrl @@ -147,17 +147,17 @@ eg017SetTemplateTabValues.worker = async (args) => { /** * Creates envelope from the template * @function - * @param {Object} args + * @param {Object} args * @returns {Envelope} An envelope definition * @private */ function makeEnvelope(args){ // Data for this method - // args.signerEmail - // args.signerName + // args.signerEmail + // args.signerName // args.signerClientId - // args.ccEmail - // args.ccName + // args.ccEmail + // args.ccName // args.templateId // The envelope has two recipients. @@ -175,7 +175,7 @@ function makeEnvelope(args){ // List item let list1 = docusign.List.constructFromObject({ value: "green", documentId: "1", pageNumber: "1", tabLabel: "list"}); - + // Checkboxes let check1 = docusign.Checkbox.constructFromObject({ tabLabel: 'ckAuthorization', selected: "true"}) @@ -187,7 +187,7 @@ function makeEnvelope(args){ let radioGroup = docusign.RadioGroup.constructFromObject({ groupName: "radio1", // You only need to provide the radio entry for the entry you're selecting - radios: + radios: [docusign.Radio.constructFromObject({value: "white", selected: "true"})] }); let text = docusign.Text.constructFromObject({ @@ -245,7 +245,7 @@ eg017SetTemplateTabValues.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg017SetTemplateTabValues', { eg: eg, csrfToken: req.csrfToken(), @@ -258,7 +258,7 @@ eg017SetTemplateTabValues.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } -} \ No newline at end of file +} diff --git a/lib/examples/eg018EnvelopeCustomFieldData.js b/lib/examples/eg018EnvelopeCustomFieldData.js index 04101968..98037557 100644 --- a/lib/examples/eg018EnvelopeCustomFieldData.js +++ b/lib/examples/eg018EnvelopeCustomFieldData.js @@ -6,7 +6,7 @@ const path = require('path') , docusign = require('docusign-esign') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg018EnvelopeCustomFieldData = exports @@ -18,27 +18,27 @@ const eg018EnvelopeCustomFieldData = exports /** * Get the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg018EnvelopeCustomFieldData.createController = async (req, res) => { // Step 1. Check the token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } if (! req.session.envelopeId) { res.render('pages/examples/eg018EnvelopeCustomFieldData', { - eg: eg, csrfToken: req.csrfToken(), + eg: eg, csrfToken: req.csrfToken(), title: "Envelope custom field data", envelopeOk: req.session.envelopeId, sourceFile: path.basename(__filename), @@ -67,7 +67,7 @@ eg018EnvelopeCustomFieldData.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } @@ -114,7 +114,7 @@ eg018EnvelopeCustomFieldData.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg018EnvelopeCustomFieldData', { eg: eg, csrfToken: req.csrfToken(), @@ -127,7 +127,7 @@ eg018EnvelopeCustomFieldData.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } -} \ No newline at end of file +} diff --git a/lib/examples/eg019AccessCodeAuthentication.js b/lib/examples/eg019AccessCodeAuthentication.js index 674d77ab..6ffbbe14 100644 --- a/lib/examples/eg019AccessCodeAuthentication.js +++ b/lib/examples/eg019AccessCodeAuthentication.js @@ -5,38 +5,36 @@ */ const path = require('path') - , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg019AccessCodeAuthentication = exports , eg = 'eg019' // This example reference. , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 - , demoDocsPath = path.resolve(__dirname, '../../demo_documents') ; /** * Create the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg019AccessCodeAuthentication.createController = async (req, res) => { // Step 1: Obtain your OAuth token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); // We could store the parameters of the requested operation so it could be // restarted automatically. But since it should be rare to have a token issue // here, we'll make the user re-enter the form data after authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } - + let body = req.body // Additional data validation might also be appropriate , signerEmail = validator.escape(body.signerEmail) @@ -53,13 +51,13 @@ eg019AccessCodeAuthentication.createController = async (req, res) => { } , results = null ; - + // Step 2. Construct your API headers let dsApiClient = new docusign.ApiClient(); dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); let envelopesApi = new docusign.EnvelopesApi(dsApiClient) - + // Step 3: Construct your envelope JSON body let env = new docusign.EnvelopeDefinition(); env.emailSubject = 'Please sign'; @@ -106,7 +104,7 @@ eg019AccessCodeAuthentication.createController = async (req, res) => { let recipients = new docusign.Recipients() recipients.Signers = [signer1]; env.recipients = recipients; - + try { // Step 4: Send the envelope results = await envelopesApi.createEnvelope(args.accountId, {envelopeDefinition: env}); @@ -117,12 +115,12 @@ eg019AccessCodeAuthentication.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // that need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -141,7 +139,7 @@ eg019AccessCodeAuthentication.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg019AccessCodeAuthentication', { eg: eg, csrfToken: req.csrfToken(), @@ -153,7 +151,7 @@ eg019AccessCodeAuthentication.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg020SmsAuthentication.js b/lib/examples/eg020SmsAuthentication.js index e00cf77d..1a2dae46 100644 --- a/lib/examples/eg020SmsAuthentication.js +++ b/lib/examples/eg020SmsAuthentication.js @@ -5,38 +5,36 @@ */ const path = require('path') - , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg020SmsAuthentication = exports , eg = 'eg020' // This example reference. , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 - , demoDocsPath = path.resolve(__dirname, '../../demo_documents') ; /** * Create the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg020SmsAuthentication.createController = async (req, res) => { // Step 1: Obtain your OAuth token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation so it could be + // We could store the parameters of the requested operation so it could be // restarted automatically. But since it should be rare to have a token issue // here, we'll make the user re-enter the form data after authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } - + let body = req.body // Additional data validation might also be appropriate , signerEmail = validator.escape(body.signerEmail) @@ -54,19 +52,19 @@ eg020SmsAuthentication.createController = async (req, res) => { , results = null ; - + // Step 2. Construct your API headers let dsApiClient = new docusign.ApiClient(); dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); let envelopesApi = new docusign.EnvelopesApi(dsApiClient) - + // Step 3: Construct your envelope JSON body let env = new docusign.EnvelopeDefinition(); env.emailSubject = 'Please sign'; env.emailBlurb = 'Sample text for email body'; env.Status = 'Sent'; - + //Add a document let doc1 = new docusign.Document() doc1.DocumentBase64 = 'JVBERi0xLjMNJeLjz9MNCjUgMCBvYmoNPDwvTGluZWFyaXplZCAxL0wgNDI3MTAvTyA3L0UgMzg3NDMvTiAxL1QgNDI0OTEvSCBbIDg5NiAxODVdPj4NZW5kb2JqDSAgICAgICAgICAgICAgICAgICAgDQp4cmVmDQo1IDMwDQowMDAwMDAwMDE2IDAwMDAwIG4NCjAwMDAwMDEwODEgMDAwMDAgbg0KMDAwMDAwMTE0MSAwMDAwMCBuDQowMDAwMDAxMzE4IDAwMDAwIG4NCjAwMDAwMDE0NzkgMDAwMDAgbg0KMDAwMDAwMTg0OCAwMDAwMCBuDQowMDAwMDAxOTk2IDAwMDAwIG4NCjAwMDAwMDIxOTcgMDAwMDAgbg0KMDAwMDAwMjYyMSAwMDAwMCBuDQowMDAwMDAyNjU2IDAwMDAwIG4NCjAwMDAwMDMzOTYgMDAwMDAgbg0KMDAwMDAwMzkwMSAwMDAwMCBuDQowMDAwMDA0NDExIDAwMDAwIG4NCjAwMDAwMDUwMTEgMDAwMDAgbg0KMDAwMDAwNTUzMCAwMDAwMCBuDQowMDAwMDA2MDQ5IDAwMDAwIG4NCjAwMDAwMDY1ODcgMDAwMDAgbg0KMDAwMDAwNjk4MyAwMDAwMCBuDQowMDAwMDA5NjkwIDAwMDAwIG4NCjAwMDAwMTYzMjUgMDAwMDAgbg0KMDAwMDAxNjU0NyAwMDAwMCBuDQowMDAwMDE3MDg3IDAwMDAwIG4NCjAwMDAwMTczMDYgMDAwMDAgbg0KMDAwMDAxNzYwMCAwMDAwMCBuDQowMDAwMDE5NTcxIDAwMDAwIG4NCjAwMDAwMTk3OTUgMDAwMDAgbg0KMDAwMDAyMDE3MiAwMDAwMCBuDQowMDAwMDMwNTAxIDAwMDAwIG4NCjAwMDAwMzA3MzMgMDAwMDAgbg0KMDAwMDAwMDg5NiAwMDAwMCBuDQp0cmFpbGVyDQo8PC9TaXplIDM1L1Jvb3QgNiAwIFIvSW5mbyA0IDAgUi9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0vUHJldiA0MjQ4MT4+DQpzdGFydHhyZWYNCjANCiUlRU9GDQogICAgICAgICAgICAgICAgDQozNCAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvSSAxMTYvTGVuZ3RoIDEwNC9TIDQwPj5zdHJlYW0NCmjeYmBgkGZgYN7DAASTHjGgAmYgZmHgWIAqKg3FDAzKDHxMFuwPghsKmWZIBDAwHWSPkN3Q6/iEfYJ8QZRXQboC94Y6hx0sPJUM+o5hC27whJ88ADWDhYFhSRiQZgTiRwABBgBLlxXzDQplbmRzdHJlYW0NZW5kb2JqDTYgMCBvYmoNPDwvTWV0YWRhdGEgMiAwIFIvUGFnZXMgMSAwIFIvVHlwZS9DYXRhbG9nPj4NZW5kb2JqDTcgMCBvYmoNPDwvQ29udGVudHNbMTQgMCBSIDE1IDAgUiAxNiAwIFIgMTcgMCBSIDE4IDAgUiAxOSAwIFIgMjAgMCBSIDIxIDAgUl0vQ3JvcEJveFswIDAgNjEyIDc5Ml0vTWVkaWFCb3hbMCAwIDYxMiA3OTJdL1BhcmVudCAxIDAgUi9SZXNvdXJjZXMgOCAwIFIvUm90YXRlIDAvVHlwZS9QYWdlPj4NZW5kb2JqDTggMCBvYmoNPDwvQ29sb3JTcGFjZTw8L0NzMSAxMyAwIFI+Pi9Gb250PDwvVFQxIDkgMCBSL1RUMyAxMCAwIFIvVFQ1IDExIDAgUi9UVDYgMTIgMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0ltYWdlQy9JbWFnZUldL1hPYmplY3Q8PC9JbTEgMzMgMCBSPj4+Pg1lbmRvYmoNOSAwIG9iag08PC9CYXNlRm9udC9aUFFQU0ErVHJlYnVjaGV0TVMvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMjQgMCBSL0xhc3RDaGFyIDExOC9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMzAxIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNTk4IDYxMyAwIDAgMCAwIDI3OCAwIDAgNTA2IDAgMCAwIDAgMCAwIDAgMCAwIDAgODUyIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDU1NyA1NDUgMzcwIDAgMCAyODUgMCAwIDI5NSA4MzAgNTQ2IDUzNyA1NTcgMCAzODkgNDA1IDAgNTQ2IDQ5MF0+Pg1lbmRvYmoNMTAgMCBvYmoNPDwvQmFzZUZvbnQvTVVLRlJOK0NhbGlicmkvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI2IDAgUi9MYXN0Q2hhciAzMy9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAyNyAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjZdPj4NZW5kb2JqDTExIDAgb2JqDTw8L0Jhc2VGb250L0hGQU1aRitDYWxpYnJpLUJvbGQvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI5IDAgUi9MYXN0Q2hhciA0NS9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAzMCAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjYgNjA2IDQ3NCAzNTUgNTAzIDUzNyA0OTQgNTM3IDM5OSAyNDYgMjc2IDQzMCA1MDddPj4NZW5kb2JqDTEyIDAgb2JqDTw8L0Jhc2VGb250L1VHSkVDSCtIZWx2ZXRpY2EvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMzIgMCBSL0xhc3RDaGFyIDEyMi9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAyNzggMzMzIDI3OCAwIDAgMCA1NTYgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDY2NyA2NjcgNzIyIDcyMiAwIDAgMCAwIDI3OCAwIDY2NyA1NTYgMCA3MjIgNzc4IDY2NyAwIDcyMiAwIDYxMSA3MjIgMCAwIDY2NyAwIDAgMCAwIDAgMCAwIDAgNTU2IDU1NiA1MDAgNTU2IDU1NiAyNzggNTU2IDU1NiAyMjIgMCA1MDAgMjIyIDgzMyA1NTYgNTU2IDU1NiAwIDMzMyA1MDAgMjc4IDU1NiA1MDAgNzIyIDUwMCA1MDAgNTAwXT4+DWVuZG9iag0xMyAwIG9iag1bL0lDQ0Jhc2VkIDIyIDAgUl0NZW5kb2JqDTE0IDAgb2JqDTw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNjcwPj5z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ACiiigAooooAKKKKACiiigApaKKAP//ZDQplbmRzdHJlYW0NZW5kb2JqDTEgMCBvYmoNPDwvQ291bnQgMS9LaWRzWzcgMCBSXS9UeXBlL1BhZ2VzPj4NZW5kb2JqDTIgMCBvYmoNPDwvTGVuZ3RoIDMzNjYvU3VidHlwZS9YTUwvVHlwZS9NZXRhZGF0YT4+c3RyZWFtDQo8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzAxNiA5MS4xNjM2MTYsIDIwMTgvMTAvMjktMTY6NTg6NDkgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGRmPSJodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIj4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDMtMjFUMTM6NTg6MDdaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5Xb3JkPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE5LTA1LTI2VDExOjE3OjE3LTA3OjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxOS0wNS0yNlQxMToxNzoxNy0wNzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHBkZjpLZXl3b3Jkcy8+CiAgICAgICAgIDxwZGY6UHJvZHVjZXI+TWFjIE9TIFggMTAuMTEuNiBRdWFydHogUERGQ29udGV4dDwvcGRmOlByb2R1Y2VyPgogICAgICAgICA8ZGM6Zm9ybWF0PmFwcGxpY2F0aW9uL3BkZjwvZGM6Zm9ybWF0PgogICAgICAgICA8ZGM6dGl0bGU+CiAgICAgICAgICAgIDxyZGY6QWx0PgogICAgICAgICAgICAgICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPk1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3g8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6QWx0PgogICAgICAgICA8L2RjOnRpdGxlPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD51dWlkOjJlNjBiMTYyLTY4MmQtNGZjOS1hYjFjLTcwMTQ0OTllMGQ0OTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+dXVpZDplYmRjZjYzOS02NWNjLTQ0YTgtODEyMi02ZDA2YWFjNzI3MDI8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4NCmVuZHN0cmVhbQ1lbmRvYmoNMyAwIG9iag1bXQ1lbmRvYmoNNCAwIG9iag08PC9BQVBMOktleXdvcmRzIDMgMCBSL0NyZWF0aW9uRGF0ZShEOjIwMTgwMzIxMTM1ODA3WikvQ3JlYXRvcihXb3JkKS9LZXl3b3JkcygpL01vZERhdGUoRDoyMDE5MDUyNjExMTcxNy0wNycwMCcpL1Byb2R1Y2VyKE1hYyBPUyBYIDEwLjExLjYgUXVhcnR6IFBERkNvbnRleHQpL1RpdGxlKE1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3gpPj4NZW5kb2JqDXhyZWYNCjAgNQ0KMDAwMDAwMDAwMCA2NTUzNSBmDQowMDAwMDM4NzQzIDAwMDAwIG4NCjAwMDAwMzg3OTQgMDAwMDAgbg0KMDAwMDA0MjIzNyAwMDAwMCBuDQowMDAwMDQyMjU1IDAwMDAwIG4NCnRyYWlsZXINCjw8L1NpemUgNS9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0+Pg0Kc3RhcnR4cmVmDQoxMTYNCiUlRU9GDQo=', @@ -75,7 +73,7 @@ eg020SmsAuthentication.createController = async (req, res) => { doc1.Name = 'Lorem'; env.documents = [doc1]; - + //Create your signature tab let signHere1 = new docusign.SignHere() signHere1.Name = 'SignHereTab'; @@ -87,10 +85,10 @@ eg020SmsAuthentication.createController = async (req, res) => { // A 1- to 8-digit integer or 32-character GUID to match recipient IDs on your own systems. // This value is referenced in the Tabs element below to assign tabs on a per-recipient basis. RecipientId = '1'; //represents your {RECIPIENT_ID} - + let signer1Tabs = new docusign.Tabs() signer1Tabs.signHereTabs = [signHere1]; - + signer1 = new docusign.Signer() signer1.Name = body.signerName; signer1.Email = body.signerEmail; @@ -99,18 +97,18 @@ eg020SmsAuthentication.createController = async (req, res) => { signer1.DeliveryMethod = 'Email'; signer1.RecipientId = '1'; //represents your {RECIPIENT_ID} signer1.Tabs = signer1Tabs; - // You may use senderprovidednumbers:[array] to add multiple phone numbers. + // You may use senderprovidednumbers:[array] to add multiple phone numbers. providedNumbers = "4155551212"; // represents your {PHONE_NUMBER} signer1.smsAuthentication = {senderprovidednumbers:[providedNumbers]}; signer1.idCheckConfigurationName = 'SMS Auth $'; signer1.requireIdLookup = 'true'; signer1.recipMayProvideNumber = 'true'; - + // Add the recipient to the envelope object let recipients = new docusign.Recipients() recipients.Signers = [signer1]; env.recipients = recipients; - + try { // Step 4: Send the envelope results = await envelopesApi.createEnvelope(args.accountId, {envelopeDefinition: env}); @@ -121,12 +119,12 @@ eg020SmsAuthentication.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // which need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -145,7 +143,7 @@ eg020SmsAuthentication.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg020SmsAuthentication', { eg: eg, csrfToken: req.csrfToken(), @@ -157,7 +155,7 @@ eg020SmsAuthentication.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } -} \ No newline at end of file +} diff --git a/lib/examples/eg021PhoneAuthentication.js b/lib/examples/eg021PhoneAuthentication.js index 1912056b..33fd2ee8 100644 --- a/lib/examples/eg021PhoneAuthentication.js +++ b/lib/examples/eg021PhoneAuthentication.js @@ -5,38 +5,36 @@ */ const path = require('path') - , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg021PhoneAuthentication = exports , eg = 'eg021' // This example reference. , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 - , demoDocsPath = path.resolve(__dirname, '../../demo_documents') ; /** * Create the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg021PhoneAuthentication.createController = async (req, res) => { // Step 1: Obtain your OAuth token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation so it could be + // We could store the parameters of the requested operation so it could be // restarted automatically. But since it should be rare to have a token issue // here, we'll make the user re-enter the form data after authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } - + let body = req.body // Additional data validation might also be appropriate , signerEmail = validator.escape(body.signerEmail) @@ -53,19 +51,19 @@ eg021PhoneAuthentication.createController = async (req, res) => { } , results = null ; - + // Step 2. Construct your API headers let dsApiClient = new docusign.ApiClient(); dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); let envelopesApi = new docusign.EnvelopesApi(dsApiClient) - + // Step 3: Construct your envelope JSON body let env = new docusign.EnvelopeDefinition(); env.emailSubject = 'Please sign'; env.emailBlurb = 'Sample text for email body'; env.Status = 'Sent'; - + //Add a document let doc1 = new docusign.Document() doc1.DocumentBase64 = 'JVBERi0xLjMNJeLjz9MNCjUgMCBvYmoNPDwvTGluZWFyaXplZCAxL0wgNDI3MTAvTyA3L0UgMzg3NDMvTiAxL1QgNDI0OTEvSCBbIDg5NiAxODVdPj4NZW5kb2JqDSAgICAgICAgICAgICAgICAgICAgDQp4cmVmDQo1IDMwDQowMDAwMDAwMDE2IDAwMDAwIG4NCjAwMDAwMDEwODEgMDAwMDAgbg0KMDAwMDAwMTE0MSAwMDAwMCBuDQowMDAwMDAxMzE4IDAwMDAwIG4NCjAwMDAwMDE0NzkgMDAwMDAgbg0KMDAwMDAwMTg0OCAwMDAwMCBuDQowMDAwMDAxOTk2IDAwMDAwIG4NCjAwMDAwMDIxOTcgMDAwMDAgbg0KMDAwMDAwMjYyMSAwMDAwMCBuDQowMDAwMDAyNjU2IDAwMDAwIG4NCjAwMDAwMDMzOTYgMDAwMDAgbg0KMDAwMDAwMzkwMSAwMDAwMCBuDQowMDAwMDA0NDExIDAwMDAwIG4NCjAwMDAwMDUwMTEgMDAwMDAgbg0KMDAwMDAwNTUzMCAwMDAwMCBuDQowMDAwMDA2MDQ5IDAwMDAwIG4NCjAwMDAwMDY1ODcgMDAwMDAgbg0KMDAwMDAwNjk4MyAwMDAwMCBuDQowMDAwMDA5NjkwIDAwMDAwIG4NCjAwMDAwMTYzMjUgMDAwMDAgbg0KMDAwMDAxNjU0NyAwMDAwMCBuDQowMDAwMDE3MDg3IDAwMDAwIG4NCjAwMDAwMTczMDYgMDAwMDAgbg0KMDAwMDAxNzYwMCAwMDAwMCBuDQowMDAwMDE5NTcxIDAwMDAwIG4NCjAwMDAwMTk3OTUgMDAwMDAgbg0KMDAwMDAyMDE3MiAwMDAwMCBuDQowMDAwMDMwNTAxIDAwMDAwIG4NCjAwMDAwMzA3MzMgMDAwMDAgbg0KMDAwMDAwMDg5NiAwMDAwMCBuDQp0cmFpbGVyDQo8PC9TaXplIDM1L1Jvb3QgNiAwIFIvSW5mbyA0IDAgUi9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0vUHJldiA0MjQ4MT4+DQpzdGFydHhyZWYNCjANCiUlRU9GDQogICAgICAgICAgICAgICAgDQozNCAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvSSAxMTYvTGVuZ3RoIDEwNC9TIDQwPj5zdHJlYW0NCmjeYmBgkGZgYN7DAASTHjGgAmYgZmHgWIAqKg3FDAzKDHxMFuwPghsKmWZIBDAwHWSPkN3Q6/iEfYJ8QZRXQboC94Y6hx0sPJUM+o5hC27whJ88ADWDhYFhSRiQZgTiRwABBgBLlxXzDQplbmRzdHJlYW0NZW5kb2JqDTYgMCBvYmoNPDwvTWV0YWRhdGEgMiAwIFIvUGFnZXMgMSAwIFIvVHlwZS9DYXRhbG9nPj4NZW5kb2JqDTcgMCBvYmoNPDwvQ29udGVudHNbMTQgMCBSIDE1IDAgUiAxNiAwIFIgMTcgMCBSIDE4IDAgUiAxOSAwIFIgMjAgMCBSIDIxIDAgUl0vQ3JvcEJveFswIDAgNjEyIDc5Ml0vTWVkaWFCb3hbMCAwIDYxMiA3OTJdL1BhcmVudCAxIDAgUi9SZXNvdXJjZXMgOCAwIFIvUm90YXRlIDAvVHlwZS9QYWdlPj4NZW5kb2JqDTggMCBvYmoNPDwvQ29sb3JTcGFjZTw8L0NzMSAxMyAwIFI+Pi9Gb250PDwvVFQxIDkgMCBSL1RUMyAxMCAwIFIvVFQ1IDExIDAgUi9UVDYgMTIgMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0ltYWdlQy9JbWFnZUldL1hPYmplY3Q8PC9JbTEgMzMgMCBSPj4+Pg1lbmRvYmoNOSAwIG9iag08PC9CYXNlRm9udC9aUFFQU0ErVHJlYnVjaGV0TVMvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMjQgMCBSL0xhc3RDaGFyIDExOC9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMzAxIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNTk4IDYxMyAwIDAgMCAwIDI3OCAwIDAgNTA2IDAgMCAwIDAgMCAwIDAgMCAwIDAgODUyIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDU1NyA1NDUgMzcwIDAgMCAyODUgMCAwIDI5NSA4MzAgNTQ2IDUzNyA1NTcgMCAzODkgNDA1IDAgNTQ2IDQ5MF0+Pg1lbmRvYmoNMTAgMCBvYmoNPDwvQmFzZUZvbnQvTVVLRlJOK0NhbGlicmkvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI2IDAgUi9MYXN0Q2hhciAzMy9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAyNyAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjZdPj4NZW5kb2JqDTExIDAgb2JqDTw8L0Jhc2VGb250L0hGQU1aRitDYWxpYnJpLUJvbGQvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI5IDAgUi9MYXN0Q2hhciA0NS9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAzMCAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjYgNjA2IDQ3NCAzNTUgNTAzIDUzNyA0OTQgNTM3IDM5OSAyNDYgMjc2IDQzMCA1MDddPj4NZW5kb2JqDTEyIDAgb2JqDTw8L0Jhc2VGb250L1VHSkVDSCtIZWx2ZXRpY2EvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMzIgMCBSL0xhc3RDaGFyIDEyMi9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAyNzggMzMzIDI3OCAwIDAgMCA1NTYgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDY2NyA2NjcgNzIyIDcyMiAwIDAgMCAwIDI3OCAwIDY2NyA1NTYgMCA3MjIgNzc4IDY2NyAwIDcyMiAwIDYxMSA3MjIgMCAwIDY2NyAwIDAgMCAwIDAgMCAwIDAgNTU2IDU1NiA1MDAgNTU2IDU1NiAyNzggNTU2IDU1NiAyMjIgMCA1MDAgMjIyIDgzMyA1NTYgNTU2IDU1NiAwIDMzMyA1MDAgMjc4IDU1NiA1MDAgNzIyIDUwMCA1MDAgNTAwXT4+DWVuZG9iag0xMyAwIG9iag1bL0lDQ0Jhc2VkIDIyIDAgUl0NZW5kb2JqDTE0IDAgb2JqDTw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNjcwPj5z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ACiiigAooooAKKKKACiiigApaKKAP//ZDQplbmRzdHJlYW0NZW5kb2JqDTEgMCBvYmoNPDwvQ291bnQgMS9LaWRzWzcgMCBSXS9UeXBlL1BhZ2VzPj4NZW5kb2JqDTIgMCBvYmoNPDwvTGVuZ3RoIDMzNjYvU3VidHlwZS9YTUwvVHlwZS9NZXRhZGF0YT4+c3RyZWFtDQo8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzAxNiA5MS4xNjM2MTYsIDIwMTgvMTAvMjktMTY6NTg6NDkgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGRmPSJodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIj4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDMtMjFUMTM6NTg6MDdaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5Xb3JkPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE5LTA1LTI2VDExOjE3OjE3LTA3OjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxOS0wNS0yNlQxMToxNzoxNy0wNzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHBkZjpLZXl3b3Jkcy8+CiAgICAgICAgIDxwZGY6UHJvZHVjZXI+TWFjIE9TIFggMTAuMTEuNiBRdWFydHogUERGQ29udGV4dDwvcGRmOlByb2R1Y2VyPgogICAgICAgICA8ZGM6Zm9ybWF0PmFwcGxpY2F0aW9uL3BkZjwvZGM6Zm9ybWF0PgogICAgICAgICA8ZGM6dGl0bGU+CiAgICAgICAgICAgIDxyZGY6QWx0PgogICAgICAgICAgICAgICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPk1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3g8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6QWx0PgogICAgICAgICA8L2RjOnRpdGxlPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD51dWlkOjJlNjBiMTYyLTY4MmQtNGZjOS1hYjFjLTcwMTQ0OTllMGQ0OTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+dXVpZDplYmRjZjYzOS02NWNjLTQ0YTgtODEyMi02ZDA2YWFjNzI3MDI8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4NCmVuZHN0cmVhbQ1lbmRvYmoNMyAwIG9iag1bXQ1lbmRvYmoNNCAwIG9iag08PC9BQVBMOktleXdvcmRzIDMgMCBSL0NyZWF0aW9uRGF0ZShEOjIwMTgwMzIxMTM1ODA3WikvQ3JlYXRvcihXb3JkKS9LZXl3b3JkcygpL01vZERhdGUoRDoyMDE5MDUyNjExMTcxNy0wNycwMCcpL1Byb2R1Y2VyKE1hYyBPUyBYIDEwLjExLjYgUXVhcnR6IFBERkNvbnRleHQpL1RpdGxlKE1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3gpPj4NZW5kb2JqDXhyZWYNCjAgNQ0KMDAwMDAwMDAwMCA2NTUzNSBmDQowMDAwMDM4NzQzIDAwMDAwIG4NCjAwMDAwMzg3OTQgMDAwMDAgbg0KMDAwMDA0MjIzNyAwMDAwMCBuDQowMDAwMDQyMjU1IDAwMDAwIG4NCnRyYWlsZXINCjw8L1NpemUgNS9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0+Pg0Kc3RhcnR4cmVmDQoxMTYNCiUlRU9GDQo=', @@ -74,7 +72,7 @@ eg021PhoneAuthentication.createController = async (req, res) => { doc1.Name = 'Lorem'; env.documents = [doc1]; - + //Create your signature tab let signHere1 = new docusign.SignHere() signHere1.Name = 'SignHereTab'; @@ -86,10 +84,10 @@ eg021PhoneAuthentication.createController = async (req, res) => { // A 1- to 8-digit integer or 32-character GUID to match recipient IDs on your own systems. // This value is referenced in the Tabs element below to assign tabs on a per-recipient basis. RecipientId = '1'; // represents your {RECIPIENT_ID} - + let signer1Tabs = new docusign.Tabs() signer1Tabs.signHereTabs = [signHere1]; - + signer1 = new docusign.Signer() signer1.Name = body.signerName; signer1.Email = body.signerEmail; @@ -98,18 +96,18 @@ eg021PhoneAuthentication.createController = async (req, res) => { signer1.DeliveryMethod = 'Email'; signer1.RecipientId = '1'; // represents your {RECIPIENT_ID} signer1.Tabs = signer1Tabs; - // You may use senderprovidednumbers:[array] to add multiple phone numbers. + // You may use senderprovidednumbers:[array] to add multiple phone numbers. providedNumbers = '4155551212'; // represents your {PHONE_NUMBER} signer1.phoneAuthentication = {senderprovidednumbers:[providedNumbers]}; signer1.idCheckConfigurationName = 'Phone Auth $'; signer1.requireIdLookup = 'true'; signer1.recipMayProvideNumber = 'true'; - + // Add the recipient to the envelope object let recipients = new docusign.Recipients() recipients.Signers = [signer1]; env.recipients = recipients; - + try { // Step 4: Send the envelope results = await envelopesApi.createEnvelope(args.accountId, {envelopeDefinition: env}); @@ -120,12 +118,12 @@ eg021PhoneAuthentication.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // which need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -144,7 +142,7 @@ eg021PhoneAuthentication.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg021PhoneAuthentication', { eg: eg, csrfToken: req.csrfToken(), @@ -156,7 +154,7 @@ eg021PhoneAuthentication.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } -} \ No newline at end of file +} diff --git a/lib/examples/eg022KbaAuthentication.js b/lib/examples/eg022KbaAuthentication.js index 1c2300c3..896b787c 100644 --- a/lib/examples/eg022KbaAuthentication.js +++ b/lib/examples/eg022KbaAuthentication.js @@ -5,40 +5,38 @@ */ const path = require('path') - , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg022KbaAuthentication = exports , eg = 'eg022' // This example reference. , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 - , demoDocsPath = path.resolve(__dirname, '../../demo_documents') ; /** * Create the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ eg022KbaAuthentication.createController = async (req, res) => { // Step 1: Obtain your OAuth token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation + // We could store the parameters of the requested operation // so it could be restarted automatically. // But since it should be rare to have a token issue here, - // we'll make the user re-enter the form data after + // we'll make the user re-enter the form data after // authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } - + let body = req.body // Additional data validation might also be appropriate , signerEmail = validator.escape(body.signerEmail) @@ -55,19 +53,19 @@ eg022KbaAuthentication.createController = async (req, res) => { } , results = null ; - + // Step 2. Construct your API headers let dsApiClient = new docusign.ApiClient(); dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); let envelopesApi = new docusign.EnvelopesApi(dsApiClient) - + // Step 3: Construct your envelope JSON body let env = new docusign.EnvelopeDefinition(); env.emailSubject = 'Please sign'; env.emailBlurb = 'Sample text for email body'; env.Status = 'Sent'; - + //Add a document let doc1 = new docusign.Document() doc1.DocumentBase64 = 'JVBERi0xLjMNJeLjz9MNCjUgMCBvYmoNPDwvTGluZWFyaXplZCAxL0wgNDI3MTAvTyA3L0UgMzg3NDMvTiAxL1QgNDI0OTEvSCBbIDg5NiAxODVdPj4NZW5kb2JqDSAgICAgICAgICAgICAgICAgICAgDQp4cmVmDQo1IDMwDQowMDAwMDAwMDE2IDAwMDAwIG4NCjAwMDAwMDEwODEgMDAwMDAgbg0KMDAwMDAwMTE0MSAwMDAwMCBuDQowMDAwMDAxMzE4IDAwMDAwIG4NCjAwMDAwMDE0NzkgMDAwMDAgbg0KMDAwMDAwMTg0OCAwMDAwMCBuDQowMDAwMDAxOTk2IDAwMDAwIG4NCjAwMDAwMDIxOTcgMDAwMDAgbg0KMDAwMDAwMjYyMSAwMDAwMCBuDQowMDAwMDAyNjU2IDAwMDAwIG4NCjAwMDAwMDMzOTYgMDAwMDAgbg0KMDAwMDAwMzkwMSAwMDAwMCBuDQowMDAwMDA0NDExIDAwMDAwIG4NCjAwMDAwMDUwMTEgMDAwMDAgbg0KMDAwMDAwNTUzMCAwMDAwMCBuDQowMDAwMDA2MDQ5IDAwMDAwIG4NCjAwMDAwMDY1ODcgMDAwMDAgbg0KMDAwMDAwNjk4MyAwMDAwMCBuDQowMDAwMDA5NjkwIDAwMDAwIG4NCjAwMDAwMTYzMjUgMDAwMDAgbg0KMDAwMDAxNjU0NyAwMDAwMCBuDQowMDAwMDE3MDg3IDAwMDAwIG4NCjAwMDAwMTczMDYgMDAwMDAgbg0KMDAwMDAxNzYwMCAwMDAwMCBuDQowMDAwMDE5NTcxIDAwMDAwIG4NCjAwMDAwMTk3OTUgMDAwMDAgbg0KMDAwMDAyMDE3MiAwMDAwMCBuDQowMDAwMDMwNTAxIDAwMDAwIG4NCjAwMDAwMzA3MzMgMDAwMDAgbg0KMDAwMDAwMDg5NiAwMDAwMCBuDQp0cmFpbGVyDQo8PC9TaXplIDM1L1Jvb3QgNiAwIFIvSW5mbyA0IDAgUi9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0vUHJldiA0MjQ4MT4+DQpzdGFydHhyZWYNCjANCiUlRU9GDQogICAgICAgICAgICAgICAgDQozNCAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvSSAxMTYvTGVuZ3RoIDEwNC9TIDQwPj5zdHJlYW0NCmjeYmBgkGZgYN7DAASTHjGgAmYgZmHgWIAqKg3FDAzKDHxMFuwPghsKmWZIBDAwHWSPkN3Q6/iEfYJ8QZRXQboC94Y6hx0sPJUM+o5hC27whJ88ADWDhYFhSRiQZgTiRwABBgBLlxXzDQplbmRzdHJlYW0NZW5kb2JqDTYgMCBvYmoNPDwvTWV0YWRhdGEgMiAwIFIvUGFnZXMgMSAwIFIvVHlwZS9DYXRhbG9nPj4NZW5kb2JqDTcgMCBvYmoNPDwvQ29udGVudHNbMTQgMCBSIDE1IDAgUiAxNiAwIFIgMTcgMCBSIDE4IDAgUiAxOSAwIFIgMjAgMCBSIDIxIDAgUl0vQ3JvcEJveFswIDAgNjEyIDc5Ml0vTWVkaWFCb3hbMCAwIDYxMiA3OTJdL1BhcmVudCAxIDAgUi9SZXNvdXJjZXMgOCAwIFIvUm90YXRlIDAvVHlwZS9QYWdlPj4NZW5kb2JqDTggMCBvYmoNPDwvQ29sb3JTcGFjZTw8L0NzMSAxMyAwIFI+Pi9Gb250PDwvVFQxIDkgMCBSL1RUMyAxMCAwIFIvVFQ1IDExIDAgUi9UVDYgMTIgMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0ltYWdlQy9JbWFnZUldL1hPYmplY3Q8PC9JbTEgMzMgMCBSPj4+Pg1lbmRvYmoNOSAwIG9iag08PC9CYXNlRm9udC9aUFFQU0ErVHJlYnVjaGV0TVMvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMjQgMCBSL0xhc3RDaGFyIDExOC9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMzAxIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNTk4IDYxMyAwIDAgMCAwIDI3OCAwIDAgNTA2IDAgMCAwIDAgMCAwIDAgMCAwIDAgODUyIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDU1NyA1NDUgMzcwIDAgMCAyODUgMCAwIDI5NSA4MzAgNTQ2IDUzNyA1NTcgMCAzODkgNDA1IDAgNTQ2IDQ5MF0+Pg1lbmRvYmoNMTAgMCBvYmoNPDwvQmFzZUZvbnQvTVVLRlJOK0NhbGlicmkvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI2IDAgUi9MYXN0Q2hhciAzMy9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAyNyAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjZdPj4NZW5kb2JqDTExIDAgb2JqDTw8L0Jhc2VGb250L0hGQU1aRitDYWxpYnJpLUJvbGQvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI5IDAgUi9MYXN0Q2hhciA0NS9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAzMCAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjYgNjA2IDQ3NCAzNTUgNTAzIDUzNyA0OTQgNTM3IDM5OSAyNDYgMjc2IDQzMCA1MDddPj4NZW5kb2JqDTEyIDAgb2JqDTw8L0Jhc2VGb250L1VHSkVDSCtIZWx2ZXRpY2EvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMzIgMCBSL0xhc3RDaGFyIDEyMi9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAyNzggMzMzIDI3OCAwIDAgMCA1NTYgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDY2NyA2NjcgNzIyIDcyMiAwIDAgMCAwIDI3OCAwIDY2NyA1NTYgMCA3MjIgNzc4IDY2NyAwIDcyMiAwIDYxMSA3MjIgMCAwIDY2NyAwIDAgMCAwIDAgMCAwIDAgNTU2IDU1NiA1MDAgNTU2IDU1NiAyNzggNTU2IDU1NiAyMjIgMCA1MDAgMjIyIDgzMyA1NTYgNTU2IDU1NiAwIDMzMyA1MDAgMjc4IDU1NiA1MDAgNzIyIDUwMCA1MDAgNTAwXT4+DWVuZG9iag0xMyAwIG9iag1bL0lDQ0Jhc2VkIDIyIDAgUl0NZW5kb2JqDTE0IDAgb2JqDTw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNjcwPj5z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ACiiigAooooAKKKKACiiigApaKKAP//ZDQplbmRzdHJlYW0NZW5kb2JqDTEgMCBvYmoNPDwvQ291bnQgMS9LaWRzWzcgMCBSXS9UeXBlL1BhZ2VzPj4NZW5kb2JqDTIgMCBvYmoNPDwvTGVuZ3RoIDMzNjYvU3VidHlwZS9YTUwvVHlwZS9NZXRhZGF0YT4+c3RyZWFtDQo8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzAxNiA5MS4xNjM2MTYsIDIwMTgvMTAvMjktMTY6NTg6NDkgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGRmPSJodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIj4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDMtMjFUMTM6NTg6MDdaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5Xb3JkPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE5LTA1LTI2VDExOjE3OjE3LTA3OjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxOS0wNS0yNlQxMToxNzoxNy0wNzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHBkZjpLZXl3b3Jkcy8+CiAgICAgICAgIDxwZGY6UHJvZHVjZXI+TWFjIE9TIFggMTAuMTEuNiBRdWFydHogUERGQ29udGV4dDwvcGRmOlByb2R1Y2VyPgogICAgICAgICA8ZGM6Zm9ybWF0PmFwcGxpY2F0aW9uL3BkZjwvZGM6Zm9ybWF0PgogICAgICAgICA8ZGM6dGl0bGU+CiAgICAgICAgICAgIDxyZGY6QWx0PgogICAgICAgICAgICAgICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPk1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3g8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6QWx0PgogICAgICAgICA8L2RjOnRpdGxlPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD51dWlkOjJlNjBiMTYyLTY4MmQtNGZjOS1hYjFjLTcwMTQ0OTllMGQ0OTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+dXVpZDplYmRjZjYzOS02NWNjLTQ0YTgtODEyMi02ZDA2YWFjNzI3MDI8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4NCmVuZHN0cmVhbQ1lbmRvYmoNMyAwIG9iag1bXQ1lbmRvYmoNNCAwIG9iag08PC9BQVBMOktleXdvcmRzIDMgMCBSL0NyZWF0aW9uRGF0ZShEOjIwMTgwMzIxMTM1ODA3WikvQ3JlYXRvcihXb3JkKS9LZXl3b3JkcygpL01vZERhdGUoRDoyMDE5MDUyNjExMTcxNy0wNycwMCcpL1Byb2R1Y2VyKE1hYyBPUyBYIDEwLjExLjYgUXVhcnR6IFBERkNvbnRleHQpL1RpdGxlKE1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3gpPj4NZW5kb2JqDXhyZWYNCjAgNQ0KMDAwMDAwMDAwMCA2NTUzNSBmDQowMDAwMDM4NzQzIDAwMDAwIG4NCjAwMDAwMzg3OTQgMDAwMDAgbg0KMDAwMDA0MjIzNyAwMDAwMCBuDQowMDAwMDQyMjU1IDAwMDAwIG4NCnRyYWlsZXINCjw8L1NpemUgNS9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0+Pg0Kc3RhcnR4cmVmDQoxMTYNCiUlRU9GDQo=', @@ -76,7 +74,7 @@ eg022KbaAuthentication.createController = async (req, res) => { doc1.Name = 'Lorem'; env.documents = [doc1]; - + //Create your signature tab let signHere1 = new docusign.SignHere() signHere1.Name = 'SignHereTab'; @@ -88,10 +86,10 @@ eg022KbaAuthentication.createController = async (req, res) => { // A 1- to 8-digit integer or 32-character GUID to match recipient IDs on your own systems. // This value is referenced in the Tabs element below to assign tabs on a per-recipient basis. RecipientId = '1'; // represents your {RECIPIENT_ID} - + let signer1Tabs = new docusign.Tabs() signer1Tabs.signHereTabs = [signHere1]; - + signer1 = new docusign.Signer() signer1.Name = body.signerName; signer1.Email = body.signerEmail; @@ -103,12 +101,12 @@ eg022KbaAuthentication.createController = async (req, res) => { signer1.idCheckConfigurationName = 'ID Check'; signer1.smsAuthentication = null; signer1.requireIdLookup = 'true'; - + // Add the recipient to the envelope object let recipients = new docusign.Recipients() recipients.Signers = [signer1]; env.recipients = recipients; - + try { // Step 4: Send the envelope results = await envelopesApi.createEnvelope(args.accountId, {envelopeDefinition: env}); @@ -119,12 +117,12 @@ eg022KbaAuthentication.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // which need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -143,7 +141,7 @@ eg022KbaAuthentication.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { res.render('pages/examples/eg022KbaAuthentication', { eg: eg, csrfToken: req.csrfToken(), @@ -155,7 +153,7 @@ eg022KbaAuthentication.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg023IdvAuthentication.js b/lib/examples/eg023IdvAuthentication.js index 8e09ecc7..a2ebaca2 100644 --- a/lib/examples/eg023IdvAuthentication.js +++ b/lib/examples/eg023IdvAuthentication.js @@ -5,38 +5,36 @@ */ const path = require('path') - , fs = require('fs-extra') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; -const eg002SigningViaEmail = exports - , eg = 'eg002' // This example reference. +const eg023IdvAuthentication = exports + , eg = 'eg023' // This example reference. , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 - , demoDocsPath = path.resolve(__dirname, '../../demo_documents') ; /** * Create the envelope - * @param {object} req Request obj + * @param {object} req Request obj * @param {object} res Response obj */ -eg002SigningViaEmail.createController = async (req, res) => { +eg023IdvAuthentication.createController = async (req, res) => { // Step 1: Obtain your OAuth token // At this point we should have a good token. But we // double-check here to enable a better UX to the user. - let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin); + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); if (! tokenOK) { req.flash('info', 'Sorry, you need to re-authenticate.'); - // We could store the parameters of the requested operation so it could be + // We could store the parameters of the requested operation so it could be // restarted automatically. But since it should be rare to have a token issue // here, we'll make the user re-enter the form data after authentication. - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } - + let body = req.body // Additional data validation might also be appropriate , signerEmail = validator.escape(body.signerEmail) @@ -53,20 +51,22 @@ eg002SigningViaEmail.createController = async (req, res) => { } , results = null ; - + // Step 2. Construct your API headers let dsApiClient = new docusign.ApiClient(); dsApiClient.setBasePath(args.basePath); dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + let envelopesApi = new docusign.EnvelopesApi(dsApiClient) - - // Step 3: Obtain your workflowId + + // Step 3: Obtain your workflowId let accountsApi = new docusign.AccountsApi(dsApiClient) + let workflowId = null try { - result = await accountsApi.getAccountIdentityVerification(args.accountId); - workflowId = result.identityVerification[0].workflowId; // represents your {WORKFLOW_ID} - console.log("WorkflowId: " + workflowId); + results = await accountsApi.getAccountIdentityVerification(args.accountId); + workflowId = results.identityVerification[0].workflowId; // represents your {WORKFLOW_ID} + console.log("WorkflowId: " + workflowId); } catch (error) { let errorBody = error && error.response && error.response.body @@ -74,17 +74,16 @@ eg002SigningViaEmail.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } - // Step 4: Construct your envelope JSON body let env = new docusign.EnvelopeDefinition(); env.emailSubject = 'Please sign'; env.emailBlurb = 'Sample text for email body'; - env.Status = 'Sent'; - + env.status = 'Sent'; + //Add a document let doc1 = new docusign.Document() doc1.DocumentBase64 = 'JVBERi0xLjMNJeLjz9MNCjUgMCBvYmoNPDwvTGluZWFyaXplZCAxL0wgNDI3MTAvTyA3L0UgMzg3NDMvTiAxL1QgNDI0OTEvSCBbIDg5NiAxODVdPj4NZW5kb2JqDSAgICAgICAgICAgICAgICAgICAgDQp4cmVmDQo1IDMwDQowMDAwMDAwMDE2IDAwMDAwIG4NCjAwMDAwMDEwODEgMDAwMDAgbg0KMDAwMDAwMTE0MSAwMDAwMCBuDQowMDAwMDAxMzE4IDAwMDAwIG4NCjAwMDAwMDE0NzkgMDAwMDAgbg0KMDAwMDAwMTg0OCAwMDAwMCBuDQowMDAwMDAxOTk2IDAwMDAwIG4NCjAwMDAwMDIxOTcgMDAwMDAgbg0KMDAwMDAwMjYyMSAwMDAwMCBuDQowMDAwMDAyNjU2IDAwMDAwIG4NCjAwMDAwMDMzOTYgMDAwMDAgbg0KMDAwMDAwMzkwMSAwMDAwMCBuDQowMDAwMDA0NDExIDAwMDAwIG4NCjAwMDAwMDUwMTEgMDAwMDAgbg0KMDAwMDAwNTUzMCAwMDAwMCBuDQowMDAwMDA2MDQ5IDAwMDAwIG4NCjAwMDAwMDY1ODcgMDAwMDAgbg0KMDAwMDAwNjk4MyAwMDAwMCBuDQowMDAwMDA5NjkwIDAwMDAwIG4NCjAwMDAwMTYzMjUgMDAwMDAgbg0KMDAwMDAxNjU0NyAwMDAwMCBuDQowMDAwMDE3MDg3IDAwMDAwIG4NCjAwMDAwMTczMDYgMDAwMDAgbg0KMDAwMDAxNzYwMCAwMDAwMCBuDQowMDAwMDE5NTcxIDAwMDAwIG4NCjAwMDAwMTk3OTUgMDAwMDAgbg0KMDAwMDAyMDE3MiAwMDAwMCBuDQowMDAwMDMwNTAxIDAwMDAwIG4NCjAwMDAwMzA3MzMgMDAwMDAgbg0KMDAwMDAwMDg5NiAwMDAwMCBuDQp0cmFpbGVyDQo8PC9TaXplIDM1L1Jvb3QgNiAwIFIvSW5mbyA0IDAgUi9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0vUHJldiA0MjQ4MT4+DQpzdGFydHhyZWYNCjANCiUlRU9GDQogICAgICAgICAgICAgICAgDQozNCAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvSSAxMTYvTGVuZ3RoIDEwNC9TIDQwPj5zdHJlYW0NCmjeYmBgkGZgYN7DAASTHjGgAmYgZmHgWIAqKg3FDAzKDHxMFuwPghsKmWZIBDAwHWSPkN3Q6/iEfYJ8QZRXQboC94Y6hx0sPJUM+o5hC27whJ88ADWDhYFhSRiQZgTiRwABBgBLlxXzDQplbmRzdHJlYW0NZW5kb2JqDTYgMCBvYmoNPDwvTWV0YWRhdGEgMiAwIFIvUGFnZXMgMSAwIFIvVHlwZS9DYXRhbG9nPj4NZW5kb2JqDTcgMCBvYmoNPDwvQ29udGVudHNbMTQgMCBSIDE1IDAgUiAxNiAwIFIgMTcgMCBSIDE4IDAgUiAxOSAwIFIgMjAgMCBSIDIxIDAgUl0vQ3JvcEJveFswIDAgNjEyIDc5Ml0vTWVkaWFCb3hbMCAwIDYxMiA3OTJdL1BhcmVudCAxIDAgUi9SZXNvdXJjZXMgOCAwIFIvUm90YXRlIDAvVHlwZS9QYWdlPj4NZW5kb2JqDTggMCBvYmoNPDwvQ29sb3JTcGFjZTw8L0NzMSAxMyAwIFI+Pi9Gb250PDwvVFQxIDkgMCBSL1RUMyAxMCAwIFIvVFQ1IDExIDAgUi9UVDYgMTIgMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0ltYWdlQy9JbWFnZUldL1hPYmplY3Q8PC9JbTEgMzMgMCBSPj4+Pg1lbmRvYmoNOSAwIG9iag08PC9CYXNlRm9udC9aUFFQU0ErVHJlYnVjaGV0TVMvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMjQgMCBSL0xhc3RDaGFyIDExOC9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMzAxIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNTk4IDYxMyAwIDAgMCAwIDI3OCAwIDAgNTA2IDAgMCAwIDAgMCAwIDAgMCAwIDAgODUyIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDU1NyA1NDUgMzcwIDAgMCAyODUgMCAwIDI5NSA4MzAgNTQ2IDUzNyA1NTcgMCAzODkgNDA1IDAgNTQ2IDQ5MF0+Pg1lbmRvYmoNMTAgMCBvYmoNPDwvQmFzZUZvbnQvTVVLRlJOK0NhbGlicmkvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI2IDAgUi9MYXN0Q2hhciAzMy9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAyNyAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjZdPj4NZW5kb2JqDTExIDAgb2JqDTw8L0Jhc2VGb250L0hGQU1aRitDYWxpYnJpLUJvbGQvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI5IDAgUi9MYXN0Q2hhciA0NS9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAzMCAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjYgNjA2IDQ3NCAzNTUgNTAzIDUzNyA0OTQgNTM3IDM5OSAyNDYgMjc2IDQzMCA1MDddPj4NZW5kb2JqDTEyIDAgb2JqDTw8L0Jhc2VGb250L1VHSkVDSCtIZWx2ZXRpY2EvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMzIgMCBSL0xhc3RDaGFyIDEyMi9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAyNzggMzMzIDI3OCAwIDAgMCA1NTYgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDY2NyA2NjcgNzIyIDcyMiAwIDAgMCAwIDI3OCAwIDY2NyA1NTYgMCA3MjIgNzc4IDY2NyAwIDcyMiAwIDYxMSA3MjIgMCAwIDY2NyAwIDAgMCAwIDAgMCAwIDAgNTU2IDU1NiA1MDAgNTU2IDU1NiAyNzggNTU2IDU1NiAyMjIgMCA1MDAgMjIyIDgzMyA1NTYgNTU2IDU1NiAwIDMzMyA1MDAgMjc4IDU1NiA1MDAgNzIyIDUwMCA1MDAgNTAwXT4+DWVuZG9iag0xMyAwIG9iag1bL0lDQ0Jhc2VkIDIyIDAgUl0NZW5kb2JqDTE0IDAgb2JqDTw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNjcwPj5z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ACiiigAooooAKKKKACiiigApaKKAP//ZDQplbmRzdHJlYW0NZW5kb2JqDTEgMCBvYmoNPDwvQ291bnQgMS9LaWRzWzcgMCBSXS9UeXBlL1BhZ2VzPj4NZW5kb2JqDTIgMCBvYmoNPDwvTGVuZ3RoIDMzNjYvU3VidHlwZS9YTUwvVHlwZS9NZXRhZGF0YT4+c3RyZWFtDQo8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzAxNiA5MS4xNjM2MTYsIDIwMTgvMTAvMjktMTY6NTg6NDkgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGRmPSJodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIj4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDMtMjFUMTM6NTg6MDdaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5Xb3JkPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE5LTA1LTI2VDExOjE3OjE3LTA3OjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxOS0wNS0yNlQxMToxNzoxNy0wNzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHBkZjpLZXl3b3Jkcy8+CiAgICAgICAgIDxwZGY6UHJvZHVjZXI+TWFjIE9TIFggMTAuMTEuNiBRdWFydHogUERGQ29udGV4dDwvcGRmOlByb2R1Y2VyPgogICAgICAgICA8ZGM6Zm9ybWF0PmFwcGxpY2F0aW9uL3BkZjwvZGM6Zm9ybWF0PgogICAgICAgICA8ZGM6dGl0bGU+CiAgICAgICAgICAgIDxyZGY6QWx0PgogICAgICAgICAgICAgICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPk1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3g8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6QWx0PgogICAgICAgICA8L2RjOnRpdGxlPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD51dWlkOjJlNjBiMTYyLTY4MmQtNGZjOS1hYjFjLTcwMTQ0OTllMGQ0OTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+dXVpZDplYmRjZjYzOS02NWNjLTQ0YTgtODEyMi02ZDA2YWFjNzI3MDI8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4NCmVuZHN0cmVhbQ1lbmRvYmoNMyAwIG9iag1bXQ1lbmRvYmoNNCAwIG9iag08PC9BQVBMOktleXdvcmRzIDMgMCBSL0NyZWF0aW9uRGF0ZShEOjIwMTgwMzIxMTM1ODA3WikvQ3JlYXRvcihXb3JkKS9LZXl3b3JkcygpL01vZERhdGUoRDoyMDE5MDUyNjExMTcxNy0wNycwMCcpL1Byb2R1Y2VyKE1hYyBPUyBYIDEwLjExLjYgUXVhcnR6IFBERkNvbnRleHQpL1RpdGxlKE1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3gpPj4NZW5kb2JqDXhyZWYNCjAgNQ0KMDAwMDAwMDAwMCA2NTUzNSBmDQowMDAwMDM4NzQzIDAwMDAwIG4NCjAwMDAwMzg3OTQgMDAwMDAgbg0KMDAwMDA0MjIzNyAwMDAwMCBuDQowMDAwMDQyMjU1IDAwMDAwIG4NCnRyYWlsZXINCjw8L1NpemUgNS9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0+Pg0Kc3RhcnR4cmVmDQoxMTYNCiUlRU9GDQo=', @@ -93,7 +92,7 @@ eg002SigningViaEmail.createController = async (req, res) => { doc1.Name = 'Lorem'; env.documents = [doc1]; - + //Create your signature tab let signHere1 = new docusign.SignHere() signHere1.Name = 'SignHereTab'; @@ -105,25 +104,25 @@ eg002SigningViaEmail.createController = async (req, res) => { // A 1- to 8-digit integer or 32-character GUID to match recipient IDs on your own systems. // This value is referenced in the Tabs element below to assign tabs on a per-recipient basis. RecipientId = '1'; // represents your {RECIPIENT_ID} - + let signer1Tabs = new docusign.Tabs() signer1Tabs.signHereTabs = [signHere1]; - - signer1 = new docusign.Signer() - signer1.Name = body.signerName; - signer1.Email = body.signerEmail; - signer1.RoutingOrder = '1'; - signer1.Status = 'Created'; - signer1.DeliveryMethod = 'Email'; - signer1.RecipientId = '1'; // represents your {RECIPIENT_ID} - signer1.Tabs = signer1Tabs; - signer1.identityVerification = {'workflowId':workflowId, 'steps': null}; - + + let signer1 = docusign.Signer.constructFromObject({ + email: body.signerEmail, + name: body.signerName, + recipientId: '1', + routingOrder: '1', + deliveryMethod: "Email", + tabs: signer1Tabs, + identityVerification: {'workflowId':workflowId, 'steps': null} + }); + // Add the recipient to the envelope object - let recipients = new docusign.Recipients() - recipients.Signers = [signer1]; + + let recipients = docusign.Recipients.constructFromObject({ signers: [signer1]}); env.recipients = recipients; - + try { // Step 5: Send the envelope results = await envelopesApi.createEnvelope(args.accountId, {envelopeDefinition: env}); @@ -134,12 +133,12 @@ eg002SigningViaEmail.createController = async (req, res) => { , errorCode = errorBody && errorBody.errorCode , errorMessage = errorBody && errorBody.message ; - // In production, may want to provide customized error messages and + // In production, may want to provide customized error messages and // remediation advice to the user. res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); } if (results) { - req.session.envelopeId = results.envelopeId; // Save for use by other examples + req.session.envelopeId = results.envelopeId; // Save for use by other examples // which need an envelopeId res.render('pages/example_done', { title: "Envelope sent", @@ -149,20 +148,20 @@ eg002SigningViaEmail.createController = async (req, res) => { } } - + // ***DS.snippet.0.end /** * Form page for this application */ -eg002SigningViaEmail.getController = (req, res) => { +eg023IdvAuthentication.getController = (req, res) => { // Check that the authentication token is ok with a long buffer time. // If needed, now is the best time to ask the user to authenticate // since they have not yet entered any information into the form. - let tokenOK = req.dsAuthCodeGrant.checkToken(); + let tokenOK = req.dsAuth.checkToken(); if (tokenOK) { - res.render('pages/examples/eg002SigningViaEmail', { + res.render('pages/examples/eg023IdvAuthentication', { eg: eg, csrfToken: req.csrfToken(), title: "Signing request by email", sourceFile: path.basename(__filename), @@ -172,7 +171,7 @@ eg002SigningViaEmail.getController = (req, res) => { }); } else { // Save the current operation so it will be resumed after authentication - req.dsAuthCodeGrant.setEg(req, eg); + req.dsAuth.setEg(req, eg); res.redirect(mustAuthenticate); } } diff --git a/lib/examples/eg024CreatePermission.js b/lib/examples/eg024CreatePermission.js new file mode 100644 index 00000000..c8a8d93e --- /dev/null +++ b/lib/examples/eg024CreatePermission.js @@ -0,0 +1,140 @@ +/** + * @file + * Example 024: Creating a permission profile + * @author DocuSign + */ + +const path = require('path') + , docusign = require('docusign-esign') + , validator = require('validator') + , dsConfig = require('../../config/index.js').config + ; + +const eg024CreatePermission = exports + , eg = 'eg024' // This example reference. + , mustAuthenticate = '/ds/mustAuthenticate' + , minimumBufferMin = 3 + ; + +/** + * Create the envelope + * @param {object} req Request obj + * @param {object} res Response obj + */ +eg024CreatePermission.createController = async (req, res) => { + + // At this point we should have a good token. But we + // double-check here to enable a better UX to the user. + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); + if (!tokenOK) { + req.flash('info', 'Sorry, you need to re-authenticate.'); + // We could store the parameters of the requested operation so it could be + // restarted automatically. But since it should be rare to have a token issue + // here, we'll make the user re-enter the form data after authentication. + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } + + let body = req.body + // Additional data validation might also be appropriate + , profileName = validator.escape(body.profileName) + // Step 1: Obtain your OAuth token + args = { + accessToken: req.user.accessToken, // represents your {ACCESS_TOKEN} + basePath: req.session.basePath, + accountId: req.session.accountId, // represents your {ACCOUNT_ID} + profileName: profileName + } + , results = null + ; + + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(args.basePath); + + // Step 2. Construct your API headers + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + let accountsApi = new docusign.AccountsApi(dsApiClient); + + // Step 3: Construct the request body + const requestBody = { + permissionProfile: { + permissionProfileName: args.profileName, + settings: { + useNewDocuSignExperienceInterface: 0, + allowBulkSending: "true", + allowEnvelopeSending: "true", + allowSignerAttachments: "true", + allowTaggingInSendAndCorrect: "true", + allowWetSigningOverride: "true", + allowedAddressBookAccess: "personalAndShared", + allowedTemplateAccess: "share", + enableRecipientViewingNotifications: "true", + enableSequentialSigningInterface: "true", + receiveCompletedSelfSignedDocumentsAsEmailLinks: "false", + signingUiVersion: "v2", + useNewSendingInterface: "true", + allowApiAccess: "true", + allowApiAccessToAccount: "true", + allowApiSendingOnBehalfOfOthers: "true", + allowApiSequentialSigning: "true", + enableApiRequestLogging: "true", + allowDocuSignDesktopClient: "false", + allowSendersToSetRecipientEmailLanguage: "true", + allowVaulting: "false", + allowedToBeEnvelopeTransferRecipient: "true", + enableTransactionPointIntegration: "false", + powerFormRole: "admin", + vaultingMode: "none" + } + } + }; + try { + // Step 4: Call the eSignature REST API + results = await accountsApi.createPermissionProfile(args.accountId, requestBody) + } + catch (error) { + let errorBody = error && error.response && error.response.body + // we can pull the DocuSign error code and message from the response body + , errorCode = errorBody && errorBody.errorCode + , errorMessage = errorBody && errorBody.message + ; + // In production, may want to provide customized error messages and + // remediation advice to the user. + res.render('pages/error', { err: error, errorCode: errorCode, errorMessage: errorMessage }); + } + + if (results) { + res.render('pages/example_done', { + title: "Profile created!", + h1: "Profile created!", + message: `The Profile has been created!
Profile ID: ${results.permissionProfileId}
Profile Name: ${results.permissionProfileName}.` + }); + } +} + +// ***DS.snippet.0.end + +/** +* Form page for this application +*/ +eg024CreatePermission.getController = async (req, res) => { + // Check that the authentication token is ok with a long buffer time. + // If needed, now is the best time to ask the user to authenticate + // since they have not yet entered any information into the form. + let tokenOK = req.dsAuth.checkToken(); + if (tokenOK) { + res.render('pages/examples/eg024CreatePermission', { + eg: eg, csrfToken: req.csrfToken(), + title: "Creating a permission profile", + sourceFile: path.basename(__filename), + sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename), + documentation: dsConfig.documentation + eg, + showDoc: dsConfig.documentation + }); + } else { + // Save the current operation so it will be resumed after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } +} diff --git a/lib/examples/eg025PermissionSetUserGroup.js b/lib/examples/eg025PermissionSetUserGroup.js new file mode 100644 index 00000000..824778c3 --- /dev/null +++ b/lib/examples/eg025PermissionSetUserGroup.js @@ -0,0 +1,133 @@ +/** + * @file + * Example 025: The permission was set + * @author DocuSign + */ + +const path = require('path') + , docusign = require('docusign-esign') + , validator = require('validator') + , dsConfig = require('../../config/index.js').config + ; + +const eg025PermissionSetUserGroup = exports + , eg = 'eg025' // This example reference. + , mustAuthenticate = '/ds/mustAuthenticate' + , minimumBufferMin = 3 + ; + +/** + * Create the envelope + * @param {object} req Request obj + * @param {object} res Response obj + */ +eg025PermissionSetUserGroup.createController = async (req, res) => { + + // At this point we should have a good token. But we + // double-check here to enable a better UX to the user. + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); + if (!tokenOK) { + req.flash('info', 'Sorry, you need to re-authenticate.'); + // We could store the parameters of the requested operation so it could be + // restarted automatically. But since it should be rare to have a token issue + // here, we'll make the user re-enter the form data after authentication. + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } + + let body = req.body + // Additional data validation might also be appropriate + , permissionProfileId = validator.escape(body.permissionProfileId) + , userGroupId = validator.escape(body.userGroupId) + + // Step 1: Obtain your OAuth token + args = { + accessToken: req.user.accessToken, // represents your {ACCESS_TOKEN} + basePath: req.session.basePath, + accountId: req.session.accountId, // represents your {ACCOUNT_ID} + } + , results = null + ; + + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(args.basePath); + + // Step 2. Construct your API headers + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + let groupApi = new docusign.GroupsApi(dsApiClient); + + // Step 3: Construct the reqeust body + const requestBody = { + groupInformation: { + groups: [ + { + permissionProfileId: permissionProfileId, + groupId: userGroupId + } + ] + } + }; + + try { + // Step 4: Call the eSignature REST API + results = await groupApi.updateGroups(args.accountId, requestBody); + } + catch (error) { + let errorBody = error && error.response && error.response.body + // we can pull the DocuSign error code and message from the response body + , errorCode = errorBody && errorBody.errorCode + , errorMessage = errorBody && errorBody.message + ; + // In production, may want to provide customized error messages and + // remediation advice to the user. + res.render('pages/error', { err: error, errorCode: errorCode, errorMessage: errorMessage }); + } + + if (results) { + res.render('pages/example_done', { + title: "The permission set", + h1: "The permission profile was successfully set to the user group", + message: "The permission profile was successfully set to the user group!" + }); + } +} + +// ***DS.snippet.0.end + +/** +* Form page for this application +*/ +eg025PermissionSetUserGroup.getController = async (req, res) => { + // Check that the authentication token is ok with a long buffer time. + // If needed, now is the best time to ask the user to authenticate + // since they have not yet entered any information into the form. + let tokenOK = req.dsAuth.checkToken(); + if (tokenOK) { + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(req.session.basePath); + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + req.user.accessToken); + + let accountApi = new docusign.AccountsApi(dsApiClient) + let listPermissions = await accountApi.listPermissions(req.session.accountId) + + let groupApi = new docusign.GroupsApi(dsApiClient) + let userGroups = await groupApi.listGroups(req.session.accountId) + + res.render('pages/examples/eg025PermissionSetUserGroup', { + eg: eg, csrfToken: req.csrfToken(), + title: "The permission set", + sourceFile: path.basename(__filename), + sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename), + documentation: dsConfig.documentation + eg, + showDoc: dsConfig.documentation, + groups: userGroups.groups || [], + permissions: listPermissions.permissionProfiles || [] + }); + } else { + // Save the current operation so it will be resumed after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } +} diff --git a/lib/examples/eg026PermissionChangeSingleSetting.js b/lib/examples/eg026PermissionChangeSingleSetting.js new file mode 100644 index 00000000..81be3100 --- /dev/null +++ b/lib/examples/eg026PermissionChangeSingleSetting.js @@ -0,0 +1,129 @@ +/** + * @file + * Example 026: Updateing individual permission profile settings + * @author DocuSign + */ + +const path = require('path') + , docusign = require('docusign-esign') + , validator = require('validator') + , dsConfig = require('../../config/index.js').config + ; + +const eg026UpdatePermissionProfile = exports + , eg = 'eg026' // This example reference. + , mustAuthenticate = '/ds/mustAuthenticate' + , minimumBufferMin = 3 + ; + + +/** + * Create the envelope + * @param {object} req Request obj + * @param {object} res Response obj + */ +eg026UpdatePermissionProfile.createController = async (req, res) => { + + + // At this point we should have a good token. But we + // double-check here to enable a better UX to the user. + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); + if (!tokenOK) { + req.flash('info', 'Sorry, you need to re-authenticate.'); + // We could store the parameters of the requested operation so it could be + // restarted automatically. But since it should be rare to have a token issue + // here, we'll make the user re-enter the form data after authentication. + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } + + let body = req.body + + // Step 1. Obtain your OAuth token + args = { + accessToken: req.user.accessToken, // represents your {ACCESS_TOKEN} + basePath: req.session.basePath, + accountId: req.session.accountId, // represents your {ACCOUNT_ID} + selectedId: validator.escape(body.profileId), + profileName: body.profileName && validator.escape(body.profileName) + } + , results = null + ; + + + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(args.basePath); + + // Step 2. Construct your API headers + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + let accountsApi = new docusign.AccountsApi(dsApiClient); + + // Step 3. Construct the request + const requestBody = { + permissionProfile: { + permissionProfileName: args.profileName + } + }; + + try { + + // Step 4. Call the eSignature REST API + results = await accountsApi.updatePermissionProfile(args.accountId, args.selectedId, + requestBody) + } + catch (error) { + let errorBody = error && error.response && error.response.body + // we can pull the DocuSign error code and message from the response body + , errorCode = errorBody && errorBody.errorCode + , errorMessage = errorBody && errorBody.message + ; + // In production, may want to provide customized error messages and + // remediation advice to the user. + res.render('pages/error', { err: error, errorCode: errorCode, errorMessage: errorMessage }); + } + + if (results) { + res.render('pages/example_done', { + title: "Permission updated", + h1: "Permission updated", + message: `The Permission has been updated.` + }); + } +} + +// ***DS.snippet.0.end + +/** + * Form page for this application + */ +eg026UpdatePermissionProfile.getController = async (req, res) => { + // Check that the authentication token is ok with a long buffer time. + // If needed, now is the best time to ask the user to authenticate + // since they have not yet entered any information into the form. + let tokenOK = req.dsAuth.checkToken(); + if (tokenOK) { + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(req.session.basePath); + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + req.user.accessToken); + + let accountApi = new docusign.AccountsApi(dsApiClient) + let profiles = await accountApi.listPermissions(req.session.accountId) + + + res.render('pages/examples/eg026PermissionChangeSingleSetting', { + eg: eg, csrfToken: req.csrfToken(), + title: "Updateing individual permission profile settings", + sourceFile: path.basename(__filename), + sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename), + documentation: dsConfig.documentation + eg, + showDoc: dsConfig.documentation, + profiles: profiles.permissionProfiles + }); + } else { + // Save the current operation so it will be resumed after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } +} diff --git a/lib/examples/eg027DeletePermission.js b/lib/examples/eg027DeletePermission.js new file mode 100644 index 00000000..bb95a029 --- /dev/null +++ b/lib/examples/eg027DeletePermission.js @@ -0,0 +1,112 @@ +/** + * @file + * Example 027: Deleting a permission profile + * @author DocuSign + */ + +const path = require('path') + , docusign = require('docusign-esign') + , validator = require('validator') + , dsConfig = require('../../config/index.js').config + ; + +const eg027DeletePermission = exports + , eg = 'eg027' // This example reference. + , mustAuthenticate = '/ds/mustAuthenticate' + , minimumBufferMin = 3 + ; + +/** + * Create the envelope + * @param {object} req Request obj + * @param {object} res Response obj + */ +eg027DeletePermission.createController = async (req, res) => { + + // At this point we should have a good token. But we + // double-check here to enable a better UX to the user. + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); + if (!tokenOK) { + req.flash('info', 'Sorry, you need to re-authenticate.'); + // We could store the parameters of the requested operation so it could be + // restarted automatically. But since it should be rare to have a token issue + // here, we'll make the user re-enter the form data after authentication. + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } + + let body = req.body + // Additional data validation might also be appropriate + , profileId = validator.escape(body.profileId) + + // Step 1: Obtain your OAuth token + args = { + accessToken: req.user.accessToken, // represents your {ACCESS_TOKEN} + basePath: req.session.basePath, + accountId: req.session.accountId, // represents your {ACCOUNT_ID} + profileId + } + , results = null + ; + + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(args.basePath); + + // Step 2. Construct your API headers + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + let accountsApi = new docusign.AccountsApi(dsApiClient); + + try { + + // Step 3. Call the eSignature API + await accountsApi.deletePermissionProfile(args.accountId, profileId) + res.render('pages/example_done', { + title: "Profile deleted!", + h1: "Profile deleted!", + message: `The Profile has been deleted!
Profile ID: ${profileId}
` + }); + } + catch { + res.render('pages/example_done', { + title: "Cannot delete profile!", + h1: "Cannot delete profile!", + message: `The Profile has not been deleted!
Profile ID: ${profileId}
` + }); + } +} + +// ***DS.snippet.0.end + +/** +* Form page for this application +*/ +eg027DeletePermission.getController = async (req, res) => { + // Check that the authentication token is ok with a long buffer time. + // If needed, now is the best time to ask the user to authenticate + // since they have not yet entered any information into the form. + let tokenOK = req.dsAuth.checkToken(); + if (tokenOK) { + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(req.session.basePath); + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + req.user.accessToken); + + let accountApi = new docusign.AccountsApi(dsApiClient) + let profiles = await accountApi.listPermissions(req.session.accountId) + let permissionProfiles = profiles.permissionProfiles + + res.render('pages/examples/eg027DeletePermission', { + eg: eg, csrfToken: req.csrfToken(), + title: "Creating a permission profile", + sourceFile: path.basename(__filename), + sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename), + documentation: dsConfig.documentation + eg, + showDoc: dsConfig.documentation, + profiles: permissionProfiles + }); + } else { + // Save the current operation so it will be resumed after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } +} diff --git a/lib/examples/eg028CreateBrand.js b/lib/examples/eg028CreateBrand.js new file mode 100644 index 00000000..2aa9e9e9 --- /dev/null +++ b/lib/examples/eg028CreateBrand.js @@ -0,0 +1,117 @@ +/** + * @file + * Example 028: Create new brand + * @author DocuSign + */ + +const path = require('path') + , docusign = require('docusign-esign') + , validator = require('validator') + , dsConfig = require('../../config/index.js').config + ; + +const eg028CreateBrand = exports + , eg = 'eg028' // This example reference + , mustAuthenticate = '/ds/mustAuthenticate' + , minimumBufferMin = 3 + ; + +/** + * Create the envelope + * @param {object} req Request obj + * @param {object} res Response obj + */ +eg028CreateBrand.createController = async (req, res) => { + // Check the token + // At this point we should have a good token. But we + // double-check here to enable a better UX to the user + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); + if (!tokenOK) { + req.flash('info', 'Sorry, you need to re-authenticate.'); + // We could store the parameters of the requested operation so it could be + // restarted automatically. But since it should be rare to have a token issue + // here, we'll make the user re-enter the form data after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } + + let body = req.body + // Additional data validation might also be appropriate + , brandName = validator.escape(body.brandName) + , defaultBrandLanguage = validator.escape(body.defaultBrandLanguage) + // Step 1. Obtain your OAuth token + args = { + accessToken: req.user.accessToken, // Represents your {ACCESS_TOKEN} + basePath: req.session.basePath, + accountId: req.session.accountId, // Represents your {ACCOUNT_ID} + brandName: brandName, + defaultBrandLanguage: defaultBrandLanguage + } + , results = null + ; + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(args.basePath); + + // Step 2. Construct your API headers + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + let accountsApi = new docusign.AccountsApi(dsApiClient) + + // Step 3. Construct the request body + let callback = { + brand: { + brandName: args.brandName, + defaultBrandLanguage: args.defaultBrandLanguage + } + } + try { + // Step 4. Call the eSignature REST API + results = await accountsApi.createBrand(args.accountId, callback); + } + catch (error) { + let errorBody = error && error.response && error.response.body + // We can pull the DocuSign error code and message from the response body + , errorCode = errorBody && errorBody.errorCode + , errorMessage = errorBody && errorBody.message + ; + // In production, you may want to provide customized error messages and + // remediation advice to the user + res.render('pages/error', { err: error, errorCode: errorCode, errorMessage: errorMessage }); + } + + if (results) { + req.session.brandId = results.brands[0].brandId; + // Save for use by other examples that need an brandId + res.render('pages/example_done', { + title: "New brand sent", + h1: "New brand sent", + message: `The brand has been created!
Brand ID: ${results.brands[0].brandId}.` + }); + } +} + +// ***DS.snippet.0.end + +/** + * Form page for this application + */ +eg028CreateBrand.getController = (req, res) => { + // Check that the authentication token is okay with a long buffer time. + // If needed, now is the best time to ask the user to authenticate, + // since they have not yet entered any information into the form + let tokenOK = req.dsAuth.checkToken(); + if (tokenOK) { + res.render('pages/examples/eg028CreateBrand', { + eg: eg, csrfToken: req.csrfToken(), + title: "Signing request by email", + sourceFile: path.basename(__filename), + sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename), + documentation: dsConfig.documentation + eg, + showDoc: dsConfig.documentation + }); + } else { + // Save the current operation so it will be resumed after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } +} diff --git a/lib/examples/eg029ApplyBrandToEnvelope.js b/lib/examples/eg029ApplyBrandToEnvelope.js new file mode 100644 index 00000000..3a1d1ec2 --- /dev/null +++ b/lib/examples/eg029ApplyBrandToEnvelope.js @@ -0,0 +1,297 @@ +/** + * @file + * Example 029: Apply brand to envelope + * @author DocuSign + */ + +const path = require('path') + , fs = require('fs-extra') + , docusign = require('docusign-esign') + , validator = require('validator') + , dsConfig = require('../../config/index.js').config + ; + +const eg029ApplyBrandToEnvelope = exports + , eg = 'eg029' // This example reference + , mustAuthenticate = '/ds/mustAuthenticate' + , minimumBufferMin = 3 + , demoDocsPath = path.resolve(__dirname, '../../demo_documents') + , doc2File = 'World_Wide_Corp_Battle_Plan_Trafalgar.docx' + , doc3File = 'World_Wide_Corp_lorem.pdf' + ; + +/** + * Create the envelope + * @param {object} req Request obj + * @param {object} res Response obj + */ +eg029ApplyBrandToEnvelope.createController = async (req, res) => { + // Check the token + // At this point we should have a good token. But we + // double-check here to enable a better UX to the user + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); + if (! tokenOK) { + req.flash('info', 'Sorry, you need to re-authenticate.'); + // We could store the parameters of the requested operation so it could be + // restarted automatically. But since it should be rare to have a token issue + // here, we'll make the user re-enter the form data after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } + + // Step 2. Call the worker method + let body = req.body + // Additional data validation might also be appropriate + , signerEmail = validator.escape(body.signerEmail) + , signerName = validator.escape(body.signerName) + , brandId = validator.escape(body.brandId) + , envelopeArgs = { + signerEmail: signerEmail, + signerName: signerName, + brandId, + status: "sent" } + , args = { + accessToken: req.user.accessToken, + basePath: req.session.basePath, + accountId: req.session.accountId, + envelopeArgs: envelopeArgs + } + , results = null + ; + + try { + results = await eg029ApplyBrandToEnvelope.worker (args) + } + catch (error) { + let errorBody = error && error.response && error.response.body + // We can pull the DocuSign error code and message from the response body + , errorCode = errorBody && errorBody.errorCode + , errorMessage = errorBody && errorBody.message + ; + // In production, you may want to provide customized error messages and + // remediation advice to the user + res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); + } + if (results) { + req.session.envelopeId = results.envelopeId; + // Save for use by other examples that need an envelopeId + res.render('pages/example_done', { + title: "Envelope sent", + h1: "Envelope sent", + message: `The envelope has been created and sent!
Envelope ID ${results.envelopeId}.` + }); + } +} + +/** + * This function does the work of creating the envelope + */ +// ***DS.snippet.0.start +eg029ApplyBrandToEnvelope.worker = async (args) => { + // Data for this method + // args.basePath + // args.accessToken + // args.accountId + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(args.basePath); + + // Step 2. Construct your API headers + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + let envelopesApi = new docusign.EnvelopesApi(dsApiClient) + , results = null; + + // Step 3. Contstruct the request body + let envelope = makeEnvelope(args.envelopeArgs) + + // Step 4. call the eSignature REST API + // Exceptions will be caught by the calling function + results = await envelopesApi.createEnvelope(args.accountId, + {envelopeDefinition: envelope}); + let envelopeId = results.envelopeId; + + console.log(`Envelope was created. EnvelopeId ${envelopeId}`); + return ({envelopeId: envelopeId}) +} + +/** + * Creates envelope + * @function + * @param {Object} args parameters for the envelope + * @returns {Envelope} An envelope definition + * @private + */ +function makeEnvelope(args){ + console.log(args.brandId) + // Data for this method + // args.signerEmail + // args.signerName + // args.brandId + // args.status + // demoDocsPath (module constant) + // doc2File (module constant) + // doc3File (module constant) + + + // document 1 (html) has tag **signature_1** + // document 2 (docx) has tag /sn1/ + // document 3 (pdf) has tag /sn1/ + // + // The envelope has two recipients. + // recipient 1 - signer + // The envelope will be sent first to the signer + + let doc2DocxBytes, doc3PdfBytes; + // Read files from a local directory + // The reads could raise an exception if the file is not available! + doc2DocxBytes = fs.readFileSync(path.resolve(demoDocsPath, doc2File)); + doc3PdfBytes = fs.readFileSync(path.resolve(demoDocsPath, doc3File)); + + // Create the envelope definition + let env = new docusign.EnvelopeDefinition(); + env.emailSubject = 'Please sign this document set'; + + // Add the documents + let doc1 = new docusign.Document() + , doc1b64 = Buffer.from(document1(args)).toString('base64') + , doc2b64 = Buffer.from(doc2DocxBytes).toString('base64') + , doc3b64 = Buffer.from(doc3PdfBytes).toString('base64') + ; + + doc1.documentBase64 = doc1b64; + doc1.name = 'Order acknowledgement'; // Can be different from actual file name + doc1.fileExtension = 'html'; // Source data format. Signed docs are always PDF + doc1.documentId = '1'; // A label used to reference the doc + + // Alternate pattern: using constructors for docs 2 and 3... + let doc2 = new docusign.Document.constructFromObject({ + documentBase64: doc2b64, + name: 'Battle Plan', // Can be different from actual file name + fileExtension: 'docx', + documentId: '2'}); + + let doc3 = new docusign.Document.constructFromObject({ + documentBase64: doc3b64, + name: 'Lorem Ipsum', // Can be different from actual file name + fileExtension: 'pdf', + documentId: '3'}); + + // The order in the docs array determines the order in the envelope + env.documents = [doc1, doc2, doc3]; + + // Create a signer recipient to sign the document, identified by name and email + // We're setting the parameters via the object constructor + let signer1 = docusign.Signer.constructFromObject({ + email: args.signerEmail, + name: args.signerName, + recipientId: '1', + routingOrder: '1'}); + // routingOrder (lower means earlier) determines the order of deliveries + // to the recipients. Parallel routing order is supported by using the + // same integer as the order for two or more recipients + + // Create signHere fields (also known as tabs) on the documents, + // We're using anchor (autoPlace) positioning + // + // The DocuSign platform searches throughout your envelope's + // documents for matching anchor strings. So the + // signHere2 tab will be used in both document 2 and 3 since they + // use the same anchor string for their "signer 1" tabs + let signHere1 = docusign.SignHere.constructFromObject({ + anchorString: '**signature_1**', + anchorYOffset: '10', anchorUnits: 'pixels', + anchorXOffset: '20'}) + , signHere2 = docusign.SignHere.constructFromObject({ + anchorString: '/sn1/', + anchorYOffset: '10', anchorUnits: 'pixels', + anchorXOffset: '20'}) + ; + + // Tabs are set per recipient/signer + let signer1Tabs = docusign.Tabs.constructFromObject({ + signHereTabs: [signHere1, signHere2]}); + signer1.tabs = signer1Tabs; + + // Add the recipients to the envelope object + let recipients = docusign.Recipients.constructFromObject({ + signers: [signer1]}); + env.recipients = recipients; + + // Request that the envelope be sent by setting status to "sent". + // To request that the envelope be created as a draft, set status to "created" + env.status = args.status; + env.brandId = args.brandId; + + return env; +} + +/** + * Creates document 1 + * @function + * @private + * @param {Object} args parameters for the envelope + * @returns {string} A document in HTML format + */ + +function document1(args) { + // Data for this method + // args.signerEmail + // args.signerName + + return ` + + + + + + +

World Wide Corp

+

Order Processing Division

+

Ordered by ${args.signerName}

+

Email: ${args.signerEmail}

+

+ Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie. Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée. Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice. Donut jujubes oat cake jelly-o. Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake. +

+ +

Agreed: **signature_1**/

+ + + ` + } +// ***DS.snippet.0.end + +/** + * Form page for this application + */ +eg029ApplyBrandToEnvelope.getController = async (req, res) => { + // Check that the authentication token is okay with a long buffer time. + // If needed, now is the best time to ask the user to authenticate, + // since they have not yet entered any information into the form + let tokenOK = req.dsAuth.checkToken() + + if (tokenOK) { + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(req.session.basePath); + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + req.user.accessToken); + + let brandApi = new docusign.AccountsApi(dsApiClient) + brandsResponse = await brandApi.listBrands(req.session.accountId) + + res.render('pages/examples/eg029ApplyBrandToEnvelope', { + eg: eg, csrfToken: req.csrfToken(), + title: "Signing request by email", + sourceFile: path.basename(__filename), + sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename), + documentation: dsConfig.documentation + eg, + showDoc: dsConfig.documentation, + brands: brandsResponse.brands || [] + }); + } else { + // Save the current operation so it will be resumed after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } +} diff --git a/lib/examples/eg030ApplyBrandToTemplate.js b/lib/examples/eg030ApplyBrandToTemplate.js new file mode 100644 index 00000000..b05936e3 --- /dev/null +++ b/lib/examples/eg030ApplyBrandToTemplate.js @@ -0,0 +1,150 @@ +/** + * @file + * Example 030: Apply Brand to Template + * @author DocuSign + */ + +const path = require('path') + , docusign = require('docusign-esign') + , validator = require('validator') + , dsConfig = require('../../config/index.js').config + ; + +const eg030ApplyBrandToTemplate = exports + , eg = 'eg030' // This example reference. + , mustAuthenticate = '/ds/mustAuthenticate' + , minimumBufferMin = 3 + ; + +/** + * Create the envelope + * @param {object} req Request obj + * @param {object} res Response obj + */ +eg030ApplyBrandToTemplate.createController = async (req, res) => { + // Check the token + // At this point we should have a good token. But we + // double-check here to enable a better UX to the user + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); + if (! tokenOK) { + req.flash('info', 'Sorry, you need to re-authenticate.'); + // We could store the parameters of the requested operation so it could be + // restarted automatically. But since it should be rare to have a token issue + // here, we'll make the user re-enter the form data after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } + + let body = req.body + // Additional data validation might also be appropriate + , signerEmail = validator.escape(body.signerEmail) + , signerName = validator.escape(body.signerName) + , ccEmail = validator.escape(body.ccEmail) + , ccName = validator.escape(body.ccName) + , brandId = validator.escape(body.brandId) + , templateId = validator.escape(body.templateId) + + //Step 1. Obtain your OAuth token + args = { + accessToken: req.user.accessToken, // Represents your {ACCESS_TOKEN} + basePath: req.session.basePath, + accountId: req.session.accountId, // Represents your {ACCOUNT_ID} + brandId: brandId, + templateId: templateId, + status: req.status, + templateRoles: [ + { + name: signerName, + email: signerEmail, + roleName: "signer" + }, + { + name: ccName, + email: ccEmail, + roleName: "cc" + } + ] + } + , results = null + ; + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(args.basePath); + + // Step 2. Construct your API headers + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + + let envelopesApi = new docusign.EnvelopesApi(dsApiClient); + + // Step 3. Construct your request body + const envDef = { + envelopeDefinition: { + templateId: args.templateId, + brandId: args.brandId, + templateRoles: args.templateRoles, + status: "sent" + } + }; + + try { + // Step 4. Call the eSignature REST API + results = await envelopesApi.createEnvelope(args.accountId, envDef) + } + catch (error) { + let errorBody = error && error.response && error.response.body + // We can pull the DocuSign error code and message from the response body + , errorCode = errorBody && errorBody.errorCode + , errorMessage = errorBody && errorBody.message + ; + // In production, you may want to provide customized error messages and + // remediation advice to the user + res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); + } + + if (results) { + res.render('pages/example_done', { + title: "Envelope sent", + h1: "Envelope sent", + message: `The envelope has been created and sent!
Envelope ID: ${results.envelopeId}.` + }); + } +} + +// ***DS.snippet.0.end + +/** + * Form page for this application + */ +eg030ApplyBrandToTemplate.getController = async (req, res) => { + // Check that the authentication token is okay with a long buffer time. + // If needed, now is the best time to ask the user to authenticate, + // since they have not yet entered any information into the form + let tokenOK = req.dsAuth.checkToken(); + if (tokenOK) { + + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(req.session.basePath); + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + req.user.accessToken); + + let templatesApi = new docusign.TemplatesApi(dsApiClient) + templatesResponse = await templatesApi.listTemplates(req.session.accountId); + + let brandApi = new docusign.AccountsApi(dsApiClient) + brandsResponse = await brandApi.listBrands(req.session.accountId) + + res.render('pages/examples/eg030ApplyBrandToTemplate', { + eg: eg, csrfToken: req.csrfToken(), + title: "Apply brand to template", + sourceFile: path.basename(__filename), + sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename), + documentation: dsConfig.documentation + eg, + showDoc: dsConfig.documentation, + brands: brandsResponse.brands || [], + templates: templatesResponse.envelopeTemplates || [] + }); + } else { + // Save the current operation so it will be resumed after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } +} diff --git a/lib/examples/eg031BulkSendEnvelopes.js b/lib/examples/eg031BulkSendEnvelopes.js new file mode 100644 index 00000000..83c2f280 --- /dev/null +++ b/lib/examples/eg031BulkSendEnvelopes.js @@ -0,0 +1,244 @@ +/** + * @file + * Example 31: Bulk sending + * @author DocuSign + */ + +const path = require('path') + , fs = require('fs-extra') + , docusign = require('docusign-esign') + , validator = require('validator') + , dsConfig = require('../../config/index.js').config + ; + +const eg031BulkSendEnvelopes = exports + , eg = 'eg031' // This example reference. + , mustAuthenticate = '/ds/mustAuthenticate' + , minimumBufferMin = 3 + , doc2File = 'World_Wide_Corp_Battle_Plan_Trafalgar.docx' + , demoDocsPath = path.resolve(__dirname, '../../demo_documents') + ; + +/** + * Create the envelope + * @param {object} req Request obj + * @param {object} res Response obj + */ +eg031BulkSendEnvelopes.createController = async (req, res) => { + // Check the token + // At this point we should have a good token. But we + // double-check here to enable a better UX to the user + let tokenOK = req.dsAuth.checkToken(minimumBufferMin); + if (! tokenOK) { + req.flash('info', 'Sorry, you need to re-authenticate.'); + // We could store the parameters of the requested operation so it could be + // restarted automatically. But since it should be rare to have a token issue + // here, we'll make the user re-enter the form data after authentication. + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } + + let body = req.body + let results + ,doc2DocxBytes = fs.readFileSync(path.resolve(demoDocsPath, doc2File)) + // Additional data validation might also be appropriate + , list1 = { + signer: { + name: validator.escape(body.signerName1), + email: validator.escape(body.signerEmail1), + }, + cc: { + name: validator.escape(body.ccName1), + email: validator.escape(body.ccEmail1), + } + } + , list2 = { + signer: { + name: validator.escape(body.signerName2), + email: validator.escape(body.signerEmail2), + }, + cc: { + name: validator.escape(body.ccName2), + email: validator.escape(body.ccEmail2), + } + } + + // Step 1. Obtain your OAuth token + args = { + accessToken: req.user.accessToken, // Represents your {ACCESS_TOKEN} + basePath: req.session.basePath, + accountId: req.session.accountId, // Represents your {ACCOUNT_ID} + } + + let recipients = (list) => { + return [ + { + + name: list.signer.name, + email: list.signer.email, + roleName: "signer" + }, + { + name: list.cc.name, + email: list.cc.email, + roleName: "CC" + } + ] + } + + // Step 2. Construct your API headers + let dsApiClient = new docusign.ApiClient(); + dsApiClient.setBasePath(args.basePath); + dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken); + + let bulkEnvelopesApi = new docusign.BulkEnvelopesApi(dsApiClient) + let envelopeApi = new docusign.EnvelopesApi(dsApiClient) + + try { + // Step 3. Create bulk list + let bulkList = await bulkEnvelopesApi.createBulkSendList(args.accountId, + { + bulkSendingList: { + name: "sample.csv", + bulkCopies:[ + { + recipients: recipients(list1) + }, + { + recipients: recipients(list2) + }, + ] + } + }) + + // Step 4. Create the draft envelope + let envelope = await envelopeApi.createEnvelope(args.accountId, + { + envelopeDefinition: { + envelopeIdStamping: "true", + emailSubject: "Please sign", + status: "Created", + documents: [ + { + documentBase64: Buffer.from(doc2DocxBytes).toString('base64'), + name: "Battle Plan", + fileExtension: "docx", + documentId: "1" + } + ] + } + }) + + // Step 5. Add an envelope custom field set to the value of your listId EnvelopeCustomFields::create) + // This Custom Field is used for tracking your Bulk Send via the Envelopes::Get method + await envelopeApi.createCustomFields(args.accountId, envelope.envelopeId, + { + customFields: { + textCustomFields: [ + { + name: "mailingListId", + required: "false", + show: "false", + value: bulkList.listId + } + ] + } + }) + + // Step 6. Add placeholder recipients + // These will be replaced by the details provided in the Bulk List uploaded during Step 3 + // Note: The name / email format used is: + // Name: Multi Bulk Recipients::{rolename} + // Email: MultiBulkRecipients-{rolename}@docusign.com + await envelopeApi.createRecipient(args.accountId, envelope.envelopeId, + { + recipients: { + signers: [ + { + name: "Multi Bulk Recipient::signer", + email: "multiBulkRecipients-signer@docusign.com", + roleName: "signer", + routingOrder: "1", + status: "created", + deliveryMethod: "email", + recipientId: "1", + recipientType: "signer" + }, + { + name: "Multi Bulk Recipient::cc", + email: "multiBulkRecipients-cc@docusign.com", + roleName: "cc", + routingOrder: "1", + status: "created", + deliveryMethod: "email", + recipientId: "2", + recipientType: "cc" + } + ] + } + }) + + //Step 7: Initiate the Bulk Send by posting your listId, and the envelopeId + let bulkResult = await bulkEnvelopesApi.createBulkSendRequest(args.accountId, bulkList.listId, + { + bulkSendRequest: { + envelopeOrTemplateId: envelope.envelopeId + } + }) + + const sleep = (milliseconds) => { + return new Promise(resolve => setTimeout(resolve, milliseconds)) + } + + await sleep(10000) + + results = await bulkEnvelopesApi.get(args.accountId, bulkResult.batchId) + } + catch (error) { + console.log(error) + let errorBody = error && error.response && error.response.body + // We can pull the DocuSign error code and message from the response body + , errorCode = errorBody && errorBody.errorCode + , errorMessage = errorBody && errorBody.message + ; + // In production, you may want to provide customized error messages and + // remediation advice to the user + res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage}); + } + + if (results) { + console.log(results) + res.render('pages/example_done', { + title: "Bulk sent", + h1: "Bulk send envelope was successfully performed!", + message: `Bulk request was sent to ${results.sent} user lists.` + }); + } +} + +// ***DS.snippet.0.end + +/** + * Form page for this application + */ +eg031BulkSendEnvelopes.getController = async (req, res) => { + // Check that the authentication token is okay with a long buffer time. + // If needed, now is the best time to ask the user to authenticate, + // since they have not yet entered any information into the form + let tokenOK = req.dsAuth.checkToken(); + if (tokenOK) { + + res.render('pages/examples/eg031BulkSendEnvelopes', { + eg: eg, csrfToken: req.csrfToken(), + title: "Bulk sending", + sourceFile: path.basename(__filename), + sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename), + documentation: dsConfig.documentation + eg, + showDoc: dsConfig.documentation + }); + } else { + // Save the current operation so it will be resumed after authentication + req.dsAuth.setEg(req, eg); + res.redirect(mustAuthenticate); + } +} diff --git a/lib/utilities/README_utilities.md b/lib/utilities/README_utilities.md index 83be004e..3da6143c 100644 --- a/lib/utilities/README_utilities.md +++ b/lib/utilities/README_utilities.md @@ -6,9 +6,9 @@ The updateSource.js file can be invoked via npm run-script update-sources ```` -It uses the github settings in the ds_configuration file +It uses the github settings in the `config/appsettings.json` file to download/update the `public/source` directory. It deletes the current content of the directory and then reloads it from the multiple GitHub repos listed in the -ds_configuration file. +`config/appsettings.json` file. diff --git a/lib/utilities/updateSources.js b/lib/utilities/updateSources.js index 8e7c1e00..f2b1c439 100644 --- a/lib/utilities/updateSources.js +++ b/lib/utilities/updateSources.js @@ -9,9 +9,10 @@ const path = require('path') , moment = require('moment') , request = require('request-promise-native') , jwt = require('jsonwebtoken') - , dsConfig = require('../../ds_configuration.js').config , sourceDirPath = path.resolve(__dirname, '../../public/source') - , ghApiUrl = 'https://api.github.com/' + , docOptions = require('../../config/documentOptions.json') + , docNames = require('../../config/documentNames.json') + , github = require('../../config/github.json') ; let ghTokenExpiration = null @@ -45,12 +46,11 @@ async function ghCreateToken() { , iat = now.unix() , exp = now.add( (9 * 60) + 30, 's').unix() , ghJWT = jwt.sign({ iat: iat, exp: exp, - iss: dsConfig.gitHubAppId }, dsConfig.gitHubPrivateKey, + iss: github.AppId }, github.PrivateKey, { algorithm: 'RS256'}) - , ghInstallationId = dsConfig.gitHubInstallationId - , url = `${ghApiUrl}app/installations/${ghInstallationId}/access_tokens` + , url = `${github.ApiUrl}app/installations/${github.InstallationId}/access_tokens` , headers = {Accept: 'application/vnd.github.machine-man-preview+json', - 'User-Agent': dsConfig.ghUserAgent} + 'User-Agent': github.UserAgent} , rawResults = await ghApi (url, headers, ghJWT, 'POST') , results = JSON.parse(rawResults) ; @@ -83,7 +83,7 @@ async function ghGetFile(owner, repo, path) { // See https://developer.github.com/v3/repos/contents/ const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}` , headers = {Accept: 'application/vnd.github.v3.raw', - 'User-Agent': dsConfig.ghUserAgent} + 'User-Agent': github.UserAgent} ; let results; await ghCheckToken(); @@ -107,7 +107,7 @@ function deleteSourceDir() { } async function doLang(item) { - let fileNames = dsConfig.docNames[item.langCode]; + let fileNames = docNames[item.langCode]; for (var eg in fileNames) { const fileName = fileNames[eg]; log (" " + fileName); @@ -195,7 +195,7 @@ function log(s) { async function start() { await ghCheckToken(); deleteSourceDir(); - for (const item of dsConfig.docOptions) { + for (const item of docOptions) { log (`${item.name} examples: `); await doLang(item); } diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 2e9af674..00000000 --- a/package-lock.json +++ /dev/null @@ -1,1663 +0,0 @@ -{ - "name": "docusign_eg03_oauth_authorization_code_grant", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "dependencies": { - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - } - } - }, - "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "connect-flash": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz", - "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA=" - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-security-policy-builder": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.0.0.tgz", - "integrity": "sha512-j+Nhmj1yfZAikJLImCvPJFE29x/UuBi+/MWqggGGc515JKaZrjuei2RhULJmy0MsstW3E3htl002bwmBNMKr7w==" - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-parser": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz", - "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==", - "requires": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6" - } - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "csrf": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csrf/-/csrf-3.1.0.tgz", - "integrity": "sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==", - "requires": { - "rndm": "1.2.0", - "tsscmp": "1.0.6", - "uid-safe": "2.1.5" - } - }, - "csurf": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/csurf/-/csurf-1.10.0.tgz", - "integrity": "sha512-fh725p0R83wA5JukCik5hdEko/LizW/Vl7pkKDa1WJUVCosg141mqaAWCScB+nkEaRMFMGbutHMOr6oBNc/j9A==", - "requires": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "csrf": "3.1.0", - "http-errors": "~1.7.2" - } - }, - "csv-stringify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-1.1.2.tgz", - "integrity": "sha1-d6QVJlgbzjOA8SsA18W7rHDIK1g=", - "requires": { - "lodash.get": "~4.4.2" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "dasherize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", - "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dns-prefetch-control": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz", - "integrity": "sha1-YN20V3dOF48flBXwyrsOhbCzALI=" - }, - "docusign-esign": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/docusign-esign/-/docusign-esign-5.0.1.tgz", - "integrity": "sha512-PPRv5j55t9a4jJVkE4ca5dNvdxnKeC52uw+/9HlIin6v6IoCyYaJHaYQnb7YQJqYAnQ0SlcTMKpMF4YRVdFd0A==", - "requires": { - "csv-stringify": "^1.0.0", - "jsonwebtoken": "8.2.0", - "passport-oauth2": "1.4.0", - "safe-buffer": "^5.1.2", - "superagent": "3.8.2" - }, - "dependencies": { - "jsonwebtoken": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.2.0.tgz", - "integrity": "sha512-1Wxh8ADP3cNyPl8tZ95WtraHXCAyXupgc0AhMHjU9er98BV+UcKsO7OJUjfhIu0Uba9A40n1oSx8dbJYrm+EoQ==", - "requires": { - "jws": "^3.1.4", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "xtend": "^4.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "dont-sniff-mimetype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz", - "integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g=" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "ejs": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.2.tgz", - "integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q==" - }, - "emitter-component": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz", - "integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "expect-ct": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz", - "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g==" - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - } - } - }, - "express-flash": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/express-flash/-/express-flash-0.0.2.tgz", - "integrity": "sha1-I9GovPP5DXB5KOSJ+Whp7K0KzaI=", - "requires": { - "connect-flash": "0.1.x" - } - }, - "express-session": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.2.tgz", - "integrity": "sha512-oy0sRsdw6n93E9wpCNWKRnSsxYnSDX9Dnr9mhZgqUEEorzcq5nshGYSZ4ZReHFhKQ80WI5iVUUSPW7u3GaKauw==", - "requires": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-headers": "~1.0.2", - "parseurl": "~1.3.3", - "safe-buffer": "5.1.2", - "uid-safe": "~2.1.5" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "feature-policy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", - "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==" - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - } - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, - "formidable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", - "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "frameguard": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz", - "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", - "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=" - }, - "fs-extra": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", - "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "helmet": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.18.0.tgz", - "integrity": "sha512-TsKlGE5UVkV0NiQ4PllV9EVfZklPjyzcMEMjWlyI/8S6epqgRT+4s4GHVgc25x0TixsKvp3L7c91HQQt5l0+QA==", - "requires": { - "depd": "2.0.0", - "dns-prefetch-control": "0.1.0", - "dont-sniff-mimetype": "1.0.0", - "expect-ct": "0.2.0", - "feature-policy": "0.3.0", - "frameguard": "3.1.0", - "helmet-crossdomain": "0.3.0", - "helmet-csp": "2.7.1", - "hide-powered-by": "1.0.0", - "hpkp": "2.0.0", - "hsts": "2.2.0", - "ienoopen": "1.1.0", - "nocache": "2.1.0", - "referrer-policy": "1.2.0", - "x-xss-protection": "1.1.0" - }, - "dependencies": { - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - } - } - }, - "helmet-crossdomain": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.3.0.tgz", - "integrity": "sha512-YiXhj0E35nC4Na5EPE4mTfoXMf9JTGpN4OtB4aLqShKuH9d2HNaJX5MQoglO6STVka0uMsHyG5lCut5Kzsy7Lg==" - }, - "helmet-csp": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.7.1.tgz", - "integrity": "sha512-sCHwywg4daQ2mY0YYwXSZRsgcCeerUwxMwNixGA7aMLkVmPTYBl7gJoZDHOZyXkqPrtuDT3s2B1A+RLI7WxSdQ==", - "requires": { - "camelize": "1.0.0", - "content-security-policy-builder": "2.0.0", - "dasherize": "2.0.0", - "platform": "1.3.5" - } - }, - "hide-powered-by": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz", - "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys=" - }, - "hpkp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", - "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" - }, - "hsts": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", - "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", - "requires": { - "depd": "2.0.0" - }, - "dependencies": { - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - } - } - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ienoopen": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", - "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^5.6.0" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "lodash": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz", - "integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==" - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "memorystore": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/memorystore/-/memorystore-1.6.1.tgz", - "integrity": "sha512-rYRjVukgBR9sptGI3IfpAjZc4SkupddhAenUhPTGprnqM8Qh863PxfXxXWlfvHpMIAkJCok28Bm7ZlOKB4U+MA==", - "requires": { - "debug": "3.1.0", - "lru-cache": "^4.0.3" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "requires": { - "mime-db": "~1.33.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "nocache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", - "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" - }, - "oauth": { - "version": "0.9.15", - "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", - "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "passport": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", - "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", - "requires": { - "passport-strategy": "1.x.x", - "pause": "0.0.1" - } - }, - "passport-docusign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/passport-docusign/-/passport-docusign-1.1.0.tgz", - "integrity": "sha512-gsjuRdmqsZwxnIhIZG3RezT2OeqmF7FdLjotq8iwAQUrO5LwfWrHnQRa58/uX6+wlEz3H5op2kGNq/nycc+NSw==", - "requires": { - "passport-oauth2": "1.x.x" - } - }, - "passport-oauth2": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.4.0.tgz", - "integrity": "sha1-9i+BWDy+EmCb585vFguTlaJ7hq0=", - "requires": { - "oauth": "0.9.x", - "passport-strategy": "1.x.x", - "uid2": "0.0.x", - "utils-merge": "1.x.x" - } - }, - "passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" - }, - "path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", - "requires": { - "process": "^0.11.1", - "util": "^0.10.3" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "platform": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", - "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "psl": { - "version": "1.1.28", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.28.tgz", - "integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==" - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "referrer-policy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", - "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "requires": { - "mime-db": "~1.37.0" - } - } - } - }, - "request-promise-core": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", - "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", - "requires": { - "lodash": "^4.17.11" - } - }, - "request-promise-native": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", - "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", - "requires": { - "request-promise-core": "1.1.2", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "rndm": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz", - "integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w=" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "sshpk": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz", - "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" - }, - "stream": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz", - "integrity": "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=", - "requires": { - "emitter-component": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "superagent": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.2.tgz", - "integrity": "sha512-gVH4QfYHcY3P0f/BZzavLreHW3T1v7hG9B+hpMQotGQqurOvhv87GcMCd6LWySmBuf+BDR44TQd0aISjVHLeNQ==", - "requires": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.0", - "debug": "^3.1.0", - "extend": "^3.0.0", - "form-data": "^2.3.1", - "formidable": "^1.1.1", - "methods": "^1.1.1", - "mime": "^1.4.1", - "qs": "^6.5.1", - "readable-stream": "^2.0.5" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "tsscmp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", - "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "dependencies": { - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - } - } - }, - "uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "requires": { - "random-bytes": "~1.0.0" - } - }, - "uid2": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", - "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - } - } - }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "requires": { - "inherits": "2.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "x-xss-protection": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.1.0.tgz", - "integrity": "sha512-rx3GzJlgEeZ08MIcDsU2vY2B1QEriUKJTSiNHHUIem6eg9pzVOr2TL3Y4Pd6TMAM5D5azGjcxqI62piITBDHVg==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } -} diff --git a/package.json b/package.json index 75faedc8..daf71fee 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "docusign_eg03_oauth_authorization_code_grant", + "name": "Docusign code examples Nodejs", "version": "1.0.0", - "description": "DocuSign Example 03 Node: OAuth Authorization Code Grant", + "description": "DocuSign eSignature Code examples using either Authorization Code Grant and JWT OAuth", "main": "index.js", "scripts": { "debug": "node --inspect-brk index.js", @@ -15,14 +15,14 @@ }, "repository": { "type": "git", - "url": "https://github.com/docusign/eg-03-node-auth-code-grant" + "url": "https://github.com/docusign/code-examples-nodejs" }, "author": "DocuSign, Inc", "license": "MIT", "bugs": { - "url": "https://github.com/docusign/eg-03-node-auth-code-grant/issues" + "url": "https://github.com/docusign/code-examples-nodejs/issues" }, - "homepage": "https://github.com/docusign/eg-03-node-auth-code-grant#readme", + "homepage": "https://github.com/docusign/code-examples-nodejs#readme", "engines": { "node": ">=8.10" }, @@ -30,7 +30,7 @@ "body-parser": "^1.19.0", "cookie-parser": "^1.4.4", "csurf": "^1.10.0", - "docusign-esign": "^5.0.1", + "docusign-esign": "^5.3.0", "ejs": "^2.6.2", "express": "^4.17.1", "express-flash": "0.0.2", diff --git a/views/pages/ds_must_authenticate.ejs b/views/pages/ds_must_authenticate.ejs index fb45361d..174a1124 100644 --- a/views/pages/ds_must_authenticate.ejs +++ b/views/pages/ds_must_authenticate.ejs @@ -3,7 +3,15 @@

Please Authenticate with DocuSign

- Authenticate with DocuSign +

+
+
+ +
+


You need to authenticate with DocuSign to continue your request.

diff --git a/views/pages/examples/eg001EmbeddedSigning.ejs b/views/pages/examples/eg001EmbeddedSigning.ejs index 14b979f9..45718314 100644 --- a/views/pages/examples/eg001EmbeddedSigning.ejs +++ b/views/pages/examples/eg001EmbeddedSigning.ejs @@ -3,9 +3,7 @@

This example sends an envelope, and then uses an embedded signing ceremony for the first signer.

Embedded signing provides a smoother user experience for the signer: the DocuSign signing ceremony is initiated from your website.

-<% if (showDoc) { %> -

Documentation about this example.

-<% } %> +<% include ../../partials/docBody %>

API methods used: Envelopes::create and diff --git a/views/pages/examples/eg002SigningViaEmail.ejs b/views/pages/examples/eg002SigningViaEmail.ejs index 3cda4498..8447a1e0 100644 --- a/views/pages/examples/eg002SigningViaEmail.ejs +++ b/views/pages/examples/eg002SigningViaEmail.ejs @@ -8,9 +8,7 @@

This is a general example of creating and sending an envelope (a signing request) to multiple recipients, with multiple documents, and with signature fields for the documents.

- <% if (showDoc) { %> -

Documentation about this example.

- <% } %> + <% include ../../partials/docBody %>

API method used: Envelopes::create. diff --git a/views/pages/examples/eg003ListEnvelopes.ejs b/views/pages/examples/eg003ListEnvelopes.ejs index b340a6a2..e24c3930 100644 --- a/views/pages/examples/eg003ListEnvelopes.ejs +++ b/views/pages/examples/eg003ListEnvelopes.ejs @@ -4,9 +4,7 @@

List the envelopes whose status has changed in the last 30 days.

This example demonstrates how to query DocuSign about envelopes sent by the current user.

-<% if (showDoc) { %> -

Documentation about this example.

- <% } %> +<% include ../../partials/docBody %>

API method used: Envelopes::listStatusChanges. diff --git a/views/pages/examples/eg004EnvelopeInfo.ejs b/views/pages/examples/eg004EnvelopeInfo.ejs index fd8e103c..117dfb85 100644 --- a/views/pages/examples/eg004EnvelopeInfo.ejs +++ b/views/pages/examples/eg004EnvelopeInfo.ejs @@ -11,9 +11,7 @@ status of an envelope changes.

-<% if (showDoc) { %> -

Documentation about this example.

-<% } %> +<% include ../../partials/docBody %>

API method used: Envelopes::get. diff --git a/views/pages/examples/eg005EnvelopeRecipients.ejs b/views/pages/examples/eg005EnvelopeRecipients.ejs index 3426f927..093b454b 100644 --- a/views/pages/examples/eg005EnvelopeRecipients.ejs +++ b/views/pages/examples/eg005EnvelopeRecipients.ejs @@ -3,9 +3,7 @@

5. List an envelope's recipients and their status

List the envelope's recipients, including their current status.

-<% if (showDoc) { %> -

Documentation about this example.

-<% } %> +<% include ../../partials/docBody %>

API method used: EnvelopeRecipients::list. diff --git a/views/pages/examples/eg006EnvelopeDocs.ejs b/views/pages/examples/eg006EnvelopeDocs.ejs index 8227b05c..6b288bcc 100644 --- a/views/pages/examples/eg006EnvelopeDocs.ejs +++ b/views/pages/examples/eg006EnvelopeDocs.ejs @@ -8,9 +8,7 @@

This method is often used to dynamically create a list of an envelope's documents in preparation for enabling your user to download one or more of the documents.

-<% if (showDoc) { %> -

Documentation about this example.

-<% } %> + <% include ../../partials/docBody %>

API method used: EnvelopeDocuments::list. diff --git a/views/pages/examples/eg007EnvelopeGetDoc.ejs b/views/pages/examples/eg007EnvelopeGetDoc.ejs index 00e60913..a2bce08d 100644 --- a/views/pages/examples/eg007EnvelopeGetDoc.ejs +++ b/views/pages/examples/eg007EnvelopeGetDoc.ejs @@ -12,9 +12,7 @@

  • The envelope's Certificate of Completion
  • -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API method used: EnvelopeDocuments::get. diff --git a/views/pages/examples/eg008CreateTemplate.ejs b/views/pages/examples/eg008CreateTemplate.ejs index 48b1cfc5..f614153b 100644 --- a/views/pages/examples/eg008CreateTemplate.ejs +++ b/views/pages/examples/eg008CreateTemplate.ejs @@ -11,9 +11,7 @@

    This example first lists the user's templates and only creates a new template if one does not already exist in your account.

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API methods used: Templates::list, diff --git a/views/pages/examples/eg009UseTemplate.ejs b/views/pages/examples/eg009UseTemplate.ejs index b70dc40c..83b0df9a 100644 --- a/views/pages/examples/eg009UseTemplate.ejs +++ b/views/pages/examples/eg009UseTemplate.ejs @@ -10,9 +10,7 @@ avoiding the need to make software changes.

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API method used: Envelopes::create. diff --git a/views/pages/examples/eg010SendBinaryDocs.ejs b/views/pages/examples/eg010SendBinaryDocs.ejs index d213a206..45e84a12 100644 --- a/views/pages/examples/eg010SendBinaryDocs.ejs +++ b/views/pages/examples/eg010SendBinaryDocs.ejs @@ -9,9 +9,7 @@

    Since binary transfer is not yet supported by the SDK, this example uses the API directly and demonstrates how to do so.

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API method used: Envelopes::create. diff --git a/views/pages/examples/eg011EmbeddedSending.ejs b/views/pages/examples/eg011EmbeddedSending.ejs index 673b7792..f9ba4343 100644 --- a/views/pages/examples/eg011EmbeddedSending.ejs +++ b/views/pages/examples/eg011EmbeddedSending.ejs @@ -14,9 +14,7 @@ needed feature (see example 13 for adding additional documents programmatically).

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API methods used: Envelopes::create and diff --git a/views/pages/examples/eg012EmbeddedConsole.ejs b/views/pages/examples/eg012EmbeddedConsole.ejs index 86d29d7a..d7812bbf 100644 --- a/views/pages/examples/eg012EmbeddedConsole.ejs +++ b/views/pages/examples/eg012EmbeddedConsole.ejs @@ -10,9 +10,7 @@ Or you can open the NDSE in a new tab for the user.

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API method used: EnvelopeViews::createConsole. diff --git a/views/pages/examples/eg013AddDocToTemplate.ejs b/views/pages/examples/eg013AddDocToTemplate.ejs index 4997d9e0..c3f64f15 100644 --- a/views/pages/examples/eg013AddDocToTemplate.ejs +++ b/views/pages/examples/eg013AddDocToTemplate.ejs @@ -16,9 +16,7 @@ signing ceremony is initiated from your website.

    <% } %> -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API methods used: Envelopes::create and diff --git a/views/pages/examples/eg014CollectPayment.ejs b/views/pages/examples/eg014CollectPayment.ejs index 08a26453..de30aef2 100644 --- a/views/pages/examples/eg014CollectPayment.ejs +++ b/views/pages/examples/eg014CollectPayment.ejs @@ -13,9 +13,7 @@ are used to position the fields in the documents.

    - <% if (showDoc) { %> -

    Documentation about this example.

    - <% } %> +<% include ../../partials/docBody %>

    API method used: Envelopes::create. diff --git a/views/pages/examples/eg015EnvelopeTabData.ejs b/views/pages/examples/eg015EnvelopeTabData.ejs index 8e85d305..ec234679 100644 --- a/views/pages/examples/eg015EnvelopeTabData.ejs +++ b/views/pages/examples/eg015EnvelopeTabData.ejs @@ -8,9 +8,7 @@ still in progress.

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API method used: EnvelopeFormData::get. diff --git a/views/pages/examples/eg016SetTabValues.ejs b/views/pages/examples/eg016SetTabValues.ejs index d042f9ac..76c718f5 100644 --- a/views/pages/examples/eg016SetTabValues.ejs +++ b/views/pages/examples/eg016SetTabValues.ejs @@ -5,9 +5,7 @@ be updated by the recipient.

    The example also sets custom metadata in the envelope via the envelope custom fields feature.

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API method used: Envelopes::create. diff --git a/views/pages/examples/eg017SetTemplateTabValues.ejs b/views/pages/examples/eg017SetTemplateTabValues.ejs index c478b8f4..efbec5a6 100644 --- a/views/pages/examples/eg017SetTemplateTabValues.ejs +++ b/views/pages/examples/eg017SetTemplateTabValues.ejs @@ -5,9 +5,7 @@ radio button and checkbox tabs.

    The example also sets custom metadata in the envelope via the envelope custom fields feature.

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API method used: Envelopes::create. diff --git a/views/pages/examples/eg018EnvelopeCustomFieldData.ejs b/views/pages/examples/eg018EnvelopeCustomFieldData.ejs index 229aa61c..d3b0047d 100644 --- a/views/pages/examples/eg018EnvelopeCustomFieldData.ejs +++ b/views/pages/examples/eg018EnvelopeCustomFieldData.ejs @@ -10,9 +10,7 @@ envelope's certificate of completion.

    an envelope.

    -<% if (showDoc) { %> -

    Documentation about this example.

    -<% } %> +<% include ../../partials/docBody %>

    API method used: EnvelopeCustomFields::list. diff --git a/views/pages/examples/eg019AccessCodeAuthentication.ejs b/views/pages/examples/eg019AccessCodeAuthentication.ejs index f7a203f7..92915c9c 100644 --- a/views/pages/examples/eg019AccessCodeAuthentication.ejs +++ b/views/pages/examples/eg019AccessCodeAuthentication.ejs @@ -7,9 +7,7 @@

    This is an example of an envelope utilizing Access-code authentication for multi-factor verification of a recipient.

    - <% if (showDoc) { %> -

    Documentation about this example.

    - <% } %> +<% include ../../partials/docBody %>

    API method used: Envelopes::create. diff --git a/views/pages/examples/eg020SmsAuthentication.ejs b/views/pages/examples/eg020SmsAuthentication.ejs index 8135d3bc..b8b5ae52 100644 --- a/views/pages/examples/eg020SmsAuthentication.ejs +++ b/views/pages/examples/eg020SmsAuthentication.ejs @@ -7,9 +7,7 @@

    This is an example of an envelope utilizing SMS authentication for multi-factor verification of a recipient.

    - <% if (showDoc) { %> -

    Documentation about this example.

    - <% } %> +<% include ../../partials/docBody %>

    API method used: Envelopes::create. diff --git a/views/pages/examples/eg021PhoneAuthentication.ejs b/views/pages/examples/eg021PhoneAuthentication.ejs index 32cd264c..9718d35a 100644 --- a/views/pages/examples/eg021PhoneAuthentication.ejs +++ b/views/pages/examples/eg021PhoneAuthentication.ejs @@ -1,18 +1,21 @@ <% include ../../partials/examplesHead %> -

    19. Send an envelope with recipient phone authentication.

    -

    Anchor text - (AutoPlace) - is used to position the signing fields in the documents. +

    21. Requiring an Phone Authentication for a Recipient

    +

    + The envelope includes a pdf document. Anchor text + (AutoPlace) + is used to position the signing fields in the documents.

    -

    This is a general example of creating an envelope (a signing request) with phone authentication for multi-factor verification of a recipient.

    +

    + This is a general example of creating and sending an envelope (a signing request) using a phone call for Recipient Authentication. +

    + - <% if (showDoc) { %> -

    Documentation about this example.

    - <% } %> - -

    API method used: - Envelopes::create. +<% include ../../partials/docBody %> + +

    + API method used: + Envelopes::create.

    The phone-number to utilize the example provided is: 415-555-1212

    @@ -33,5 +36,5 @@ - -<% include ../../partials/examplesFoot %> + +<% include ../../partials/examplesFoot %> \ No newline at end of file diff --git a/views/pages/examples/eg022KbaAuthentication.ejs b/views/pages/examples/eg022KbaAuthentication.ejs index 79ba6f0d..766a82e4 100644 --- a/views/pages/examples/eg022KbaAuthentication.ejs +++ b/views/pages/examples/eg022KbaAuthentication.ejs @@ -1,39 +1,43 @@ <% include ../../partials/examplesHead %> - -

    19. Send an envelope with recipient knowledged based authentication (KBA).

    -

    Anchor text - (AutoPlace) - is used to position the signing fields in the documents. +

    22. Requiring Knowledge Based Authentication (KBA) for a Recipient

    +

    + The envelope includes a pdf document. Anchor text + (AutoPlace) + is used to position the signing fields in the documents. +

    +

    + This is a general example of creating and sending an envelope (a signing request) using KBA for Recipient Authentication.

    -

    This is a general example of creating an envelope (a signing request) with - knowledge-based authentication using top of the mind questions. The service - queries public records information from Lexis Nexis and provides a form multi-factor verification for a recipient.

    - <% if (showDoc) { %> -

    Documentation about this example.

    - <% } %> - -

    API method used: - Envelopes::create. +<% include ../../partials/docBody %> + +

    API method used: + Envelopes::create.

    +

    The access-code to utilize the example provided is: NJ9@D1

    + <% include ../../partials/gitSource %> +
    -
    - - - We'll never share your email with anyone else. -
    -
    - - -
    - - +

    + Note: The Access Code for this example is the Signer Name. +

    +
    + + + We'll never share your email with anyone else. +
    +
    + + +
    + + +
    - -<% include ../../partials/examplesFoot %> +<% include ../../partials/examplesFoot %> \ No newline at end of file diff --git a/views/pages/examples/eg023IdvAuthentication.ejs b/views/pages/examples/eg023IdvAuthentication.ejs index 4f7d8a13..e8f4202f 100644 --- a/views/pages/examples/eg023IdvAuthentication.ejs +++ b/views/pages/examples/eg023IdvAuthentication.ejs @@ -1,37 +1,42 @@ <% include ../../partials/examplesHead %> -

    19. Send an envelope with recipient Id Verification authentication.

    -

    Anchor text - (AutoPlace) - is used to position the signing fields in the documents. +

    23. Requiring Id Verification for a Recipient

    +

    + The envelope includes a pdf document. Anchor text + (AutoPlace) + is used to position the signing fields in the documents.

    -

    This is an example of an envelope utilizing IDV authentication for multi-factor verification of a recipient. IDV is a service offered by DocuSign that allows your reicpient to upload a photo of a government issued id for verification.

    +

    + This is a general example of creating and sending an envelope (a signing request) using ID Verification for Recipient Authentication. +

    + +<% include ../../partials/docBody %> - <% if (showDoc) { %> -

    Documentation about this example.

    - <% } %> - -

    API method used: - Envelopes::create. +

    + API method used: + Envelopes::create.

    -

    The access-code to utilize the example provided is: NJ9@D1

    <% include ../../partials/gitSource %>
    -
    +

    + Note: The Access Code for this example is the Signer Name. +

    + +
    We'll never share your email with anyone else. -
    -
    +
    +
    -
    - - + value="<%= locals.dsConfig.signerName %>" required> +
    + +
    - + <% include ../../partials/examplesFoot %> diff --git a/views/pages/examples/eg024CreatePermission.ejs b/views/pages/examples/eg024CreatePermission.ejs new file mode 100644 index 00000000..918a061f --- /dev/null +++ b/views/pages/examples/eg024CreatePermission.ejs @@ -0,0 +1,26 @@ +<% include ../../partials/examplesHead %> + +

    24. Creating a permission profile

    +

    + This code example demonstrates how to create a permission profile +

    + +<% include ../../partials/docBody %> + +

    + API method used: + AccountPermissionProfiles::create.. +

    + +<% include ../../partials/gitSource %> + +
    +
    + + +
    + + +
    + +<% include ../../partials/examplesFoot %> diff --git a/views/pages/examples/eg025PermissionSetUserGroup.ejs b/views/pages/examples/eg025PermissionSetUserGroup.ejs new file mode 100644 index 00000000..6bc8f516 --- /dev/null +++ b/views/pages/examples/eg025PermissionSetUserGroup.ejs @@ -0,0 +1,42 @@ +<% include ../../partials/examplesHead %> + +

    25. Setting a permission profile.

    + +

    + Updates the group name and modifies, or sets, the permission profile for the group. +

    + +<% include ../../partials/docBody %> + +

    + API method used: + Groups::update. +

    + + +<% include ../../partials/gitSource %> + +
    +
    + + +
    + +
    + + +
    + + + +
    + +<% include ../../partials/examplesFoot %> diff --git a/views/pages/examples/eg026PermissionChangeSingleSetting.ejs b/views/pages/examples/eg026PermissionChangeSingleSetting.ejs new file mode 100644 index 00000000..96c7a75f --- /dev/null +++ b/views/pages/examples/eg026PermissionChangeSingleSetting.ejs @@ -0,0 +1,104 @@ +<% include ../../partials/examplesHead %> + +

    26. Updating individual permission settings

    +

    + This code example demonstrates how to edit individual permission settings on a permissions profile with the eSignature REST API. +

    + +<% include ../../partials/docBody %> + +

    + API method used: + AccountPermissionProfiles::update. +

    + +<% include ../../partials/gitSource %> + +
    +
    + +
    + + +
    + + + + +
    + Allow sequential signing
    + Allow sending to bulk list
    + Can send envelope
    + Allow signer attachments
    + Allow tagging in send and correct
    + Allow signing override +
    +
    + +
    + +
    +
    + +
    + +
    +
    + + Allow recipient viewed notifications
    + Enable sequential signing interface
    + Self-signed email notification +
    +
    + +
    + +
    +
    + + Use new sending interface
    + Allow API access
    + Allow view and manage envelope rights through API
    + Allow send on behalf of other users through API
    + Allow API sequential signing
    + Enable API request logging
    + Allow DocuSign desktop client
    + Allow senders to set recipient email language
    + Allow vaulting
    + Allow receipt of transferred envelopes
    + Enable transaction point integration +
    +
    + +
    + +
    + + + + + + + +<% include ../../partials/examplesFoot %> diff --git a/views/pages/examples/eg027DeletePermission.ejs b/views/pages/examples/eg027DeletePermission.ejs new file mode 100644 index 00000000..ece0c074 --- /dev/null +++ b/views/pages/examples/eg027DeletePermission.ejs @@ -0,0 +1,41 @@ +<% include ../../partials/examplesHead %> + +

    27. Deleting a permission profile

    +

    + Permission profiles are collections of account settings that determine the behavior and actions available + to the user groups to which they're applied. + This code example demonstrates how to delete a permission profile with the eSignature REST API. +

    + +<% include ../../partials/docBody %> + +

    + API method used: + AccountPermissionProfiles::delete.. +

    + + +<% include ../../partials/gitSource %> + +<% if (profiles.length == 0) { %> +

    Problem: please first create the profile using example 24.
    Thank you.

    + +
    + +
    +<% } else { %> +
    +
    + + +
    + + +
    +<% } %> + +<% include ../../partials/examplesFoot %> diff --git a/views/pages/examples/eg028CreateBrand.ejs b/views/pages/examples/eg028CreateBrand.ejs new file mode 100644 index 00000000..0101f1ee --- /dev/null +++ b/views/pages/examples/eg028CreateBrand.ejs @@ -0,0 +1,39 @@ +<% include ../../partials/examplesHead %> + +

    28. Creating a brand

    +

    + The brand includes a Brand Name Configure Brands. +

    +

    + This code example demonstrates how to create a brand. +

    + +<% include ../../partials/docBody %> + +

    + API method used: + AccountBrands::create. +

    + +<% include ../../partials/gitSource %> +
    +

    + New brand +

    + +
    + + +
    +
    + + +
    + + +
    + +<% include ../../partials/examplesFoot %> diff --git a/views/pages/examples/eg029ApplyBrandToEnvelope.ejs b/views/pages/examples/eg029ApplyBrandToEnvelope.ejs new file mode 100644 index 00000000..2c815c28 --- /dev/null +++ b/views/pages/examples/eg029ApplyBrandToEnvelope.ejs @@ -0,0 +1,57 @@ +<% include ../../partials/examplesHead %> + +

    29. Applying a brand to an envelope.

    + +

    + The envelope includes a pdf document. Anchor text + (AutoPlace) + is used to position the signing fields in the documents. +

    +

    + This code example demonstrates how to apply a brand to an envelope. +

    + +<% include ../../partials/docBody %> + +

    API method used: + Envelopes::create. +

    + +<% include ../../partials/gitSource %> + +<% if (brands.length == 0) { %> +

    Problem: please first create the brand using example 28.
    + Thank you.

    + +
    + +
    +<% } else { %> +
    +
    + + + We'll never share your email with anyone else. +
    +
    + + +
    +
    + + +
    + + + +
    +<% } %> + +<% include ../../partials/examplesFoot %> diff --git a/views/pages/examples/eg030ApplyBrandToTemplate.ejs b/views/pages/examples/eg030ApplyBrandToTemplate.ejs new file mode 100644 index 00000000..ca38b99b --- /dev/null +++ b/views/pages/examples/eg030ApplyBrandToTemplate.ejs @@ -0,0 +1,78 @@ +<% include ../../partials/examplesHead %> + +

    30. Applying a brand to a template

    +

    + This code example demonstrates how to apply a brand to a +

    + +<% include ../../partials/docBody %> + +

    + API method used: + Envelopes::create. +

    + +

    The access-code to utilize the example provided is: NJ9@D1

    +<% include ../../partials/gitSource %> + +<% if (brands.length !== 0 && templates.length !== 0) { %> +
    +
    + + + We'll never share your email with anyone else. +
    +
    + + +
    +
    + + + The email and/or name for the cc recipient must be different from the signer. +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +<% } else if(brands.length === 0) { %> +

    Problem: please first create the brand using example 28.
    + Thank you.

    + +
    + +
    +<% } else if(templates.length === 0) { %> +

    Problem: please first create the template using example 8.
    + Thank you.

    + +
    + +
    +<% } %> + +<% include ../../partials/examplesFoot %> diff --git a/views/pages/examples/eg031BulkSendEnvelopes.ejs b/views/pages/examples/eg031BulkSendEnvelopes.ejs new file mode 100644 index 00000000..1de93418 --- /dev/null +++ b/views/pages/examples/eg031BulkSendEnvelopes.ejs @@ -0,0 +1,79 @@ +<% include ../../partials/examplesHead %> + +

    31. Bulk sending envelopes to multiple recipients.

    + +

    + Method BulkSend::createBulkSendList creates a bulk send list that you can use to send an envelope to up to 1,000 recipients at once. +

    + +<% include ../../partials/docBody %> + +

    + API methods used: + EnvelopeRecipients::create, + Envelopes::create, + BulkEnvelopes::get, + EnvelopeCustomFields::create, + BulkSend::createBulkSendList + EnvelopeRecipients::create. +

    + + +<% include ../../partials/gitSource %> + +
    + +
    Bulk copy #1
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    Bulk copy #2
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    + + +<% include ../../partials/examplesFoot %> \ No newline at end of file diff --git a/views/pages/index.ejs b/views/pages/index.ejs index 3c2aafc0..68fbab1a 100644 --- a/views/pages/index.ejs +++ b/views/pages/index.ejs @@ -6,10 +6,9 @@

    Welcome!

    <% if (locals.dsConfig.multiSourceChooser) { %>

    Welcome to the DocuSign code examples with - OAuth Authorization Code Grant.

    + OAuth Authorization Code Grant and JWT.

    <% } else { %> -

    Welcome to the DocuSign Node.JS examples with - OAuth Authorization Code Grant.

    +

    >Welcome to the DocuSign Python examples using multiple OAuth flows (JWT and Authorization Code Grant).

    <% } %>
    <% } %> @@ -17,8 +16,7 @@

    Welcome

    -

    This launcher both demonstrates use of the OAuth Authorization Code Grant flow and includes multiple workflow - examples for the DocuSign eSignature REST API.

    +

    This launcher includes the following examples for the DocuSign eSignature REST API.

    <% if (locals.dsConfig.multiSourceChooser) { %>
    - \ No newline at end of file From d6e49920fe3407a3ef69e7031d34eff7d511467c Mon Sep 17 00:00:00 2001 From: Aaron Wilde Date: Tue, 9 Jun 2020 22:14:25 -0700 Subject: [PATCH 2/5] change from nodejs to code-examples-node --- README.md | 10 +++++----- package.json | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 729eb265..1656d4e6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Node.JS Launcher Code Examples -### Github repo: [code-examples-nodejs](./) +### Github repo: [code-examples-node](./) ## Introduction This repo is a Node.JS application that demonstrates: @@ -140,8 +140,8 @@ When the token expires, it updates automatically. The signer and the cc email cannot be the same. ### Installation steps -1. Download or clone this repository to your workstation to directory **code-examples-nodejs** -1. **cd code-examples-nodejs** +1. Download or clone this repository to your workstation to directory **code-examples-node** +1. **cd code-examples-node** 1. **npm install** 1. *Either:* @@ -166,7 +166,7 @@ When the token expires, it updates automatically. 2. Create a new API key in the Admin panel: https://admindemo.docusign.com/api-integrator-key, take note of the public key. 3. Set a redirect URI of `http://localhost:5000/ds/callback` as mentioned in the installation steps above for the API key you make in step 2. 4. Generate an RSA keypair in the administrator console on the DocuSign developer sandbox and copy the private key to a secure location. -5. Create a new file in your repo source folder named **private.key**, and paste in that copied RSA private key, then save it. +5. Copy and paste the new RSA private key into an enviorntmental variable or into **config/appsettings.json** file. REMOVE the automatic spaces that may be generated by the IDE as this will cause JWT to fail. 6. Update the file **config/appsettings.json** and include the newly created API key from step 2 as well as your account user id GUID which is also found on the Admin panel: `https://admindemo.docusign.com/api-integrator-key`. From there you should be able to run the launcher using **npm start** then selecting **JSON Web Token** when authenticaing your account. @@ -177,7 +177,7 @@ To use the payments example, create a test payments gateway for your developer sandbox account. See the -[PAYMENTS_INSTALLATION.md](./eg-03-node-auth-code-grant/blob/master/PAYMENTS_INSTALLATION.md) +[PAYMENTS_INSTALLATION.md](./code-examples-node/blob/master/PAYMENTS_INSTALLATION.md) file for instructions. Then add the payment gateway account id to the **config/appsettings.json** file. diff --git a/package.json b/package.json index cb152ca2..0c3880ed 100644 --- a/package.json +++ b/package.json @@ -15,14 +15,14 @@ }, "repository": { "type": "git", - "url": "https://github.com/docusign/code-examples-nodejs" + "url": "https://github.com/docusign/code-examples-node" }, "author": "DocuSign, Inc", "license": "MIT", "bugs": { - "url": "https://github.com/docusign/code-examples-nodejs/issues" + "url": "https://github.com/docusign/code-examples-node/issues" }, - "homepage": "https://github.com/docusign/code-examples-nodejs#readme", + "homepage": "https://github.com/docusign/code-examples-node#readme", "engines": { "node": ">=8.10" }, From 24390a8e5c8f3e304ffd59a5a83ccf3d23c68537 Mon Sep 17 00:00:00 2001 From: Aaron Wilde Date: Tue, 9 Jun 2020 22:20:59 -0700 Subject: [PATCH 3/5] updates to readme --- README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1656d4e6..c25d7b4b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Node.JS Launcher Code Examples +# Docusign eSignature Node.js Code Examples ### Github repo: [code-examples-node](./) ## Introduction @@ -114,7 +114,7 @@ This repo is a Node.JS application that demonstrates: ## Included OAuth grant types: -* Authentication with Docusign via [Authorization Code Grant flow](https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-code-grant) . +* Authentication with Docusign via [Authorization Code Grant flow](https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-code-grant). When the token expires, the user is asked to re-authenticate. The **refresh token** is not used in this example. @@ -145,11 +145,12 @@ When the token expires, it updates automatically. 1. **npm install** 1. *Either:* - * Update the file **config/appsettings.json** in the project's root directory - with the Integration Key - and other settings, *or* + * Copy the the file **config/appsettings.example.json** to **config/appsettings.json** with the Integration Key and other settings, + + *or* + * Create and export environment variables for the settings. - See the **config/appsettings.json** file + See the **config/appsettings.example.json** file for the names of the environment variables. **Note:** Protect your Integration Key and secret--If you update @@ -164,10 +165,16 @@ When the token expires, it updates automatically. 1. Create a developer sandbox account on developers.docusign.com if you don't already have one. 2. Create a new API key in the Admin panel: https://admindemo.docusign.com/api-integrator-key, take note of the public key. -3. Set a redirect URI of `http://localhost:5000/ds/callback` as mentioned in the installation steps above for the API key you make in step 2. -4. Generate an RSA keypair in the administrator console on the DocuSign developer sandbox and copy the private key to a secure location. -5. Copy and paste the new RSA private key into an enviorntmental variable or into **config/appsettings.json** file. REMOVE the automatic spaces that may be generated by the IDE as this will cause JWT to fail. -6. Update the file **config/appsettings.json** and include the newly created API key from step 2 as well as your account user id GUID which is also found on the Admin panel: `https://admindemo.docusign.com/api-integrator-key`. +3. Generate an RSA keypair in the administrator console on the DocuSign developer sandbox and copy the private key to a secure location. +4. * Copy the the file **config/appsettings.example.json** to **config/appsettings.json** with the Integration Key and other settings, NOTE, your IDE may automatically insert indentation spaces... delete those automatically formatted strings as they will break your RSA private key. + + *or* + + * Create and export environment variables for the settings. + See the **config/appsettings.example.json** file + for the names of the environment variables. + +5. Update the file **config/appsettings.json** and include the newly created API key from step 2 as well as your account user id GUID which is also found on the Admin panel: `https://admindemo.docusign.com/api-integrator-key`. From there you should be able to run the launcher using **npm start** then selecting **JSON Web Token** when authenticaing your account. From 49b1f7124ed2d2e5ab15a7ba695b12e685d78a4e Mon Sep 17 00:00:00 2001 From: Aaron Wilde Date: Wed, 10 Jun 2020 17:50:15 -0700 Subject: [PATCH 4/5] jwt settings + updated links --- README.md | 37 ++++++++----------- config/appsettings.json | 4 +- config/index.js | 2 + docs/Adding_examples.md | 4 +- index.js | 2 +- lib/examples/eg011EmbeddedSending.js | 2 +- lib/examples/eg013AddDocToTemplate.js | 2 +- lib/examples/eg023IdvAuthentication.js | 13 +------ lib/examples/eg024CreatePermission.js | 2 +- lib/examples/eg031BulkSendEnvelopes.js | 1 + package.json | 10 ++--- .../eg026PermissionChangeSingleSetting.ejs | 2 +- views/pages/index_examples.ejs | 2 +- views/pages/index_launchers.ejs | 14 +++---- 14 files changed, 43 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index c25d7b4b..a1a9ff60 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Docusign eSignature Node.js Code Examples +# Node.JS Launcher Code Examples -### Github repo: [code-examples-node](./) +### Github repo: [code-examples-nodejs](./) ## Introduction This repo is a Node.JS application that demonstrates: @@ -73,7 +73,7 @@ This repo is a Node.JS application that demonstrates: [Source.](./lib/examples/eg021PhoneAuthentication.js) This example sends and envelope that requires entering in a voice-based response code for the purpose of multi-factor authentication. 1. **Requiring Knowledge-Based Authentication (KBA) for a Recipient** - [Source.](https://github.com/docusign/eg-03-node-auth-code-grant/blob/master/lib/examples/eg022KbaAuthentication.js) + [Source.](./lib/examples/eg022KbaAuthentication.js) This example sends and envelope that requires passing a Public records check to validate identity for the purpose of multi-factor authentication. 1. **Requiring ID Verification (IDV) for a recipient** [Source.](./lib/examples/eg023IdvAuthentication.js) @@ -112,9 +112,11 @@ This repo is a Node.JS application that demonstrates: Firstly, creates a bulk send recipients list, and then creates an envelope. After that, initiates bulk envelope sending. + + ## Included OAuth grant types: -* Authentication with Docusign via [Authorization Code Grant flow](https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-code-grant). +* Authentication with Docusign via [Authorization Code Grant flow](https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-code-grant) . When the token expires, the user is asked to re-authenticate. The **refresh token** is not used in this example. @@ -140,17 +142,16 @@ When the token expires, it updates automatically. The signer and the cc email cannot be the same. ### Installation steps -1. Download or clone this repository to your workstation to directory **code-examples-node** -1. **cd code-examples-node** +1. Download or clone this repository to your workstation to directory **code-examples-nodejs** +1. **cd code-examples-nodejs** 1. **npm install** 1. *Either:* - * Copy the the file **config/appsettings.example.json** to **config/appsettings.json** with the Integration Key and other settings, - - *or* - + * Update the file **config/appsettings.json** in the project's root directory + with the Integration Key + and other settings, *or* * Create and export environment variables for the settings. - See the **config/appsettings.example.json** file + See the **config/appsettings.json** file for the names of the environment variables. **Note:** Protect your Integration Key and secret--If you update @@ -165,16 +166,10 @@ When the token expires, it updates automatically. 1. Create a developer sandbox account on developers.docusign.com if you don't already have one. 2. Create a new API key in the Admin panel: https://admindemo.docusign.com/api-integrator-key, take note of the public key. -3. Generate an RSA keypair in the administrator console on the DocuSign developer sandbox and copy the private key to a secure location. -4. * Copy the the file **config/appsettings.example.json** to **config/appsettings.json** with the Integration Key and other settings, NOTE, your IDE may automatically insert indentation spaces... delete those automatically formatted strings as they will break your RSA private key. - - *or* - - * Create and export environment variables for the settings. - See the **config/appsettings.example.json** file - for the names of the environment variables. - -5. Update the file **config/appsettings.json** and include the newly created API key from step 2 as well as your account user id GUID which is also found on the Admin panel: `https://admindemo.docusign.com/api-integrator-key`. +3. Set a redirect URI of `http://localhost:5000/ds/callback` as mentioned in the installation steps above for the API key you make in step 2. +4. Generate an RSA keypair in the administrator console on the DocuSign developer sandbox and copy the private key to a secure location. +5. Create a new file in your repo source folder named **private.key**, and paste in that copied RSA private key, then save it. +6. Update the file **config/appsettings.json** and include the newly created API key from step 2 as well as your account user id GUID which is also found on the Admin panel: `https://admindemo.docusign.com/api-integrator-key`. From there you should be able to run the launcher using **npm start** then selecting **JSON Web Token** when authenticaing your account. diff --git a/config/appsettings.json b/config/appsettings.json index 3ca38d9c..858a514a 100644 --- a/config/appsettings.json +++ b/config/appsettings.json @@ -3,6 +3,8 @@ "dsClientSecret": "{CLIENT_SECRET}", "signerEmail": "{USER_EMAIL}", "signerName": "{USER_FULLNAME}", + "privateKey": "{DS_PRIVATE_KEY}", + "impersonatedUserGuid": "{DS_IMPERSONATED_USER_GUID}", "appUrl": "http://localhost:5000", "production": false, "debug": true, @@ -15,7 +17,7 @@ "gatewayAccountId": "", "gatewayName": "stripe", "gatewayDisplayName": "Stripe", - "githubExampleUrl": "https://github.com/docusign/eg-03-node-auth-code-grant/tree/master/lib/examples/", + "githubExampleUrl": "https://github.com/docusign/code-examples-node/tree/master/lib/examples/", "documentation": null, "multiSourceChooser": false } \ No newline at end of file diff --git a/config/index.js b/config/index.js index 2635c4a1..f780c026 100644 --- a/config/index.js +++ b/config/index.js @@ -13,6 +13,8 @@ settings.signerEmail = process.env.DS_SIGNER_EMAIL || settings.signerEmail; settings.signerName = process.env.DS_SIGNER_NAME || settings.signerName; settings.dsClientId = process.env.DS_CLIENT_ID || settings.dsClientId; settings.appUrl = process.env.DS_APP_URL || settings.appUrl; +settings.privateKey = process.env.DS_PRIVATE_KEY || settings.privateKey; +settings.impersonatedUserGuid = process.env.DS_IMPERSONATED_USER_GUID || settings.impersonatedUserGuid; exports.config = { dsOauthServer, diff --git a/docs/Adding_examples.md b/docs/Adding_examples.md index 8d1ff023..7e55cd59 100644 --- a/docs/Adding_examples.md +++ b/docs/Adding_examples.md @@ -8,8 +8,8 @@ All contributions must use the MIT License. First, discuss your plans with the DevCenter Examples Manager (Larry Kluger) via apihelp@docusign.com. He'll assign you an example number. -A new example can be added to any of the `eg-03-` series of -launchers, except for the curl repo. +A new example can be added to any of the `code-examples` series of +launchers. After your new example has been accepted, the DevCenter team will arrange to have it ported to the other SDK examples. diff --git a/index.js b/index.js index dd8561ec..6b30e4dd 100755 --- a/index.js +++ b/index.js @@ -66,7 +66,7 @@ let app = express() .use(cookieParser()) .use(session({ secret: dsConfig.sessionSecret, - name: 'ds-eg03-session', + name: 'ds-launcher-session', cookie: {maxAge: max_session_min * 60000}, saveUninitialized: true, resave: true, diff --git a/lib/examples/eg011EmbeddedSending.js b/lib/examples/eg011EmbeddedSending.js index 0a76f738..b3980fce 100644 --- a/lib/examples/eg011EmbeddedSending.js +++ b/lib/examples/eg011EmbeddedSending.js @@ -15,7 +15,7 @@ const eg011EmbeddedSending = exports , eg = 'eg011' // This example reference. , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 - , dsReturnUrl = dsConfig.appUrl + '/ds-return' + , dsReturnUrl = dsConfig.appUrl + '/ds-return' ; /** diff --git a/lib/examples/eg013AddDocToTemplate.js b/lib/examples/eg013AddDocToTemplate.js index fad768fa..8c835368 100644 --- a/lib/examples/eg013AddDocToTemplate.js +++ b/lib/examples/eg013AddDocToTemplate.js @@ -15,7 +15,7 @@ const eg013AddDocToTemplate = exports , mustAuthenticate = '/ds/mustAuthenticate' , minimumBufferMin = 3 , signerClientId = 1000 // The id of the signer within this application. - , dsReturnUrl = dsConfig.appUrl + '/ds-return' + , dsReturnUrl = dsConfig.appUrl + '/ds-return' , dsPingUrl = dsConfig.appUrl + '/' // Url that will be pinged by the DocuSign Signing Ceremony via Ajax ; diff --git a/lib/examples/eg023IdvAuthentication.js b/lib/examples/eg023IdvAuthentication.js index 64ff201c..a2ebaca2 100644 --- a/lib/examples/eg023IdvAuthentication.js +++ b/lib/examples/eg023IdvAuthentication.js @@ -83,6 +83,7 @@ eg023IdvAuthentication.createController = async (req, res) => { env.emailSubject = 'Please sign'; env.emailBlurb = 'Sample text for email body'; env.status = 'Sent'; + //Add a document let doc1 = new docusign.Document() doc1.DocumentBase64 = 'JVBERi0xLjMNJeLjz9MNCjUgMCBvYmoNPDwvTGluZWFyaXplZCAxL0wgNDI3MTAvTyA3L0UgMzg3NDMvTiAxL1QgNDI0OTEvSCBbIDg5NiAxODVdPj4NZW5kb2JqDSAgICAgICAgICAgICAgICAgICAgDQp4cmVmDQo1IDMwDQowMDAwMDAwMDE2IDAwMDAwIG4NCjAwMDAwMDEwODEgMDAwMDAgbg0KMDAwMDAwMTE0MSAwMDAwMCBuDQowMDAwMDAxMzE4IDAwMDAwIG4NCjAwMDAwMDE0NzkgMDAwMDAgbg0KMDAwMDAwMTg0OCAwMDAwMCBuDQowMDAwMDAxOTk2IDAwMDAwIG4NCjAwMDAwMDIxOTcgMDAwMDAgbg0KMDAwMDAwMjYyMSAwMDAwMCBuDQowMDAwMDAyNjU2IDAwMDAwIG4NCjAwMDAwMDMzOTYgMDAwMDAgbg0KMDAwMDAwMzkwMSAwMDAwMCBuDQowMDAwMDA0NDExIDAwMDAwIG4NCjAwMDAwMDUwMTEgMDAwMDAgbg0KMDAwMDAwNTUzMCAwMDAwMCBuDQowMDAwMDA2MDQ5IDAwMDAwIG4NCjAwMDAwMDY1ODcgMDAwMDAgbg0KMDAwMDAwNjk4MyAwMDAwMCBuDQowMDAwMDA5NjkwIDAwMDAwIG4NCjAwMDAwMTYzMjUgMDAwMDAgbg0KMDAwMDAxNjU0NyAwMDAwMCBuDQowMDAwMDE3MDg3IDAwMDAwIG4NCjAwMDAwMTczMDYgMDAwMDAgbg0KMDAwMDAxNzYwMCAwMDAwMCBuDQowMDAwMDE5NTcxIDAwMDAwIG4NCjAwMDAwMTk3OTUgMDAwMDAgbg0KMDAwMDAyMDE3MiAwMDAwMCBuDQowMDAwMDMwNTAxIDAwMDAwIG4NCjAwMDAwMzA3MzMgMDAwMDAgbg0KMDAwMDAwMDg5NiAwMDAwMCBuDQp0cmFpbGVyDQo8PC9TaXplIDM1L1Jvb3QgNiAwIFIvSW5mbyA0IDAgUi9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0vUHJldiA0MjQ4MT4+DQpzdGFydHhyZWYNCjANCiUlRU9GDQogICAgICAgICAgICAgICAgDQozNCAwIG9iag08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvSSAxMTYvTGVuZ3RoIDEwNC9TIDQwPj5zdHJlYW0NCmjeYmBgkGZgYN7DAASTHjGgAmYgZmHgWIAqKg3FDAzKDHxMFuwPghsKmWZIBDAwHWSPkN3Q6/iEfYJ8QZRXQboC94Y6hx0sPJUM+o5hC27whJ88ADWDhYFhSRiQZgTiRwABBgBLlxXzDQplbmRzdHJlYW0NZW5kb2JqDTYgMCBvYmoNPDwvTWV0YWRhdGEgMiAwIFIvUGFnZXMgMSAwIFIvVHlwZS9DYXRhbG9nPj4NZW5kb2JqDTcgMCBvYmoNPDwvQ29udGVudHNbMTQgMCBSIDE1IDAgUiAxNiAwIFIgMTcgMCBSIDE4IDAgUiAxOSAwIFIgMjAgMCBSIDIxIDAgUl0vQ3JvcEJveFswIDAgNjEyIDc5Ml0vTWVkaWFCb3hbMCAwIDYxMiA3OTJdL1BhcmVudCAxIDAgUi9SZXNvdXJjZXMgOCAwIFIvUm90YXRlIDAvVHlwZS9QYWdlPj4NZW5kb2JqDTggMCBvYmoNPDwvQ29sb3JTcGFjZTw8L0NzMSAxMyAwIFI+Pi9Gb250PDwvVFQxIDkgMCBSL1RUMyAxMCAwIFIvVFQ1IDExIDAgUi9UVDYgMTIgMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0ltYWdlQy9JbWFnZUldL1hPYmplY3Q8PC9JbTEgMzMgMCBSPj4+Pg1lbmRvYmoNOSAwIG9iag08PC9CYXNlRm9udC9aUFFQU0ErVHJlYnVjaGV0TVMvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMjQgMCBSL0xhc3RDaGFyIDExOC9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMzAxIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNTk4IDYxMyAwIDAgMCAwIDI3OCAwIDAgNTA2IDAgMCAwIDAgMCAwIDAgMCAwIDAgODUyIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDU1NyA1NDUgMzcwIDAgMCAyODUgMCAwIDI5NSA4MzAgNTQ2IDUzNyA1NTcgMCAzODkgNDA1IDAgNTQ2IDQ5MF0+Pg1lbmRvYmoNMTAgMCBvYmoNPDwvQmFzZUZvbnQvTVVLRlJOK0NhbGlicmkvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI2IDAgUi9MYXN0Q2hhciAzMy9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAyNyAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjZdPj4NZW5kb2JqDTExIDAgb2JqDTw8L0Jhc2VGb250L0hGQU1aRitDYWxpYnJpLUJvbGQvRmlyc3RDaGFyIDMzL0ZvbnREZXNjcmlwdG9yIDI5IDAgUi9MYXN0Q2hhciA0NS9TdWJ0eXBlL1RydWVUeXBlL1RvVW5pY29kZSAzMCAwIFIvVHlwZS9Gb250L1dpZHRoc1syMjYgNjA2IDQ3NCAzNTUgNTAzIDUzNyA0OTQgNTM3IDM5OSAyNDYgMjc2IDQzMCA1MDddPj4NZW5kb2JqDTEyIDAgb2JqDTw8L0Jhc2VGb250L1VHSkVDSCtIZWx2ZXRpY2EvRW5jb2RpbmcvTWFjUm9tYW5FbmNvZGluZy9GaXJzdENoYXIgMzIvRm9udERlc2NyaXB0b3IgMzIgMCBSL0xhc3RDaGFyIDEyMi9TdWJ0eXBlL1RydWVUeXBlL1R5cGUvRm9udC9XaWR0aHNbMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAyNzggMzMzIDI3OCAwIDAgMCA1NTYgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDY2NyA2NjcgNzIyIDcyMiAwIDAgMCAwIDI3OCAwIDY2NyA1NTYgMCA3MjIgNzc4IDY2NyAwIDcyMiAwIDYxMSA3MjIgMCAwIDY2NyAwIDAgMCAwIDAgMCAwIDAgNTU2IDU1NiA1MDAgNTU2IDU1NiAyNzggNTU2IDU1NiAyMjIgMCA1MDAgMjIyIDgzMyA1NTYgNTU2IDU1NiAwIDMzMyA1MDAgMjc4IDU1NiA1MDAgNzIyIDUwMCA1MDAgNTAwXT4+DWVuZG9iag0xMyAwIG9iag1bL0lDQ0Jhc2VkIDIyIDAgUl0NZW5kb2JqDTE0IDAgb2JqDTw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNjcwPj5z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ACiiigAooooAKKKKACiiigApaKKAP//ZDQplbmRzdHJlYW0NZW5kb2JqDTEgMCBvYmoNPDwvQ291bnQgMS9LaWRzWzcgMCBSXS9UeXBlL1BhZ2VzPj4NZW5kb2JqDTIgMCBvYmoNPDwvTGVuZ3RoIDMzNjYvU3VidHlwZS9YTUwvVHlwZS9NZXRhZGF0YT4+c3RyZWFtDQo8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pgo8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzAxNiA5MS4xNjM2MTYsIDIwMTgvMTAvMjktMTY6NTg6NDkgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGRmPSJodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIj4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTgtMDMtMjFUMTM6NTg6MDdaPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5Xb3JkPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE5LTA1LTI2VDExOjE3OjE3LTA3OjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxOS0wNS0yNlQxMToxNzoxNy0wNzowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHBkZjpLZXl3b3Jkcy8+CiAgICAgICAgIDxwZGY6UHJvZHVjZXI+TWFjIE9TIFggMTAuMTEuNiBRdWFydHogUERGQ29udGV4dDwvcGRmOlByb2R1Y2VyPgogICAgICAgICA8ZGM6Zm9ybWF0PmFwcGxpY2F0aW9uL3BkZjwvZGM6Zm9ybWF0PgogICAgICAgICA8ZGM6dGl0bGU+CiAgICAgICAgICAgIDxyZGY6QWx0PgogICAgICAgICAgICAgICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPk1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3g8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6QWx0PgogICAgICAgICA8L2RjOnRpdGxlPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD51dWlkOjJlNjBiMTYyLTY4MmQtNGZjOS1hYjFjLTcwMTQ0OTllMGQ0OTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+dXVpZDplYmRjZjYzOS02NWNjLTQ0YTgtODEyMi02ZDA2YWFjNzI3MDI8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4NCmVuZHN0cmVhbQ1lbmRvYmoNMyAwIG9iag1bXQ1lbmRvYmoNNCAwIG9iag08PC9BQVBMOktleXdvcmRzIDMgMCBSL0NyZWF0aW9uRGF0ZShEOjIwMTgwMzIxMTM1ODA3WikvQ3JlYXRvcihXb3JkKS9LZXl3b3JkcygpL01vZERhdGUoRDoyMDE5MDUyNjExMTcxNy0wNycwMCcpL1Byb2R1Y2VyKE1hYyBPUyBYIDEwLjExLjYgUXVhcnR6IFBERkNvbnRleHQpL1RpdGxlKE1pY3Jvc29mdCBXb3JkIC0gV29ybGRfV2lkZV9Db3JwX2xvcmVtLmRvY3gpPj4NZW5kb2JqDXhyZWYNCjAgNQ0KMDAwMDAwMDAwMCA2NTUzNSBmDQowMDAwMDM4NzQzIDAwMDAwIG4NCjAwMDAwMzg3OTQgMDAwMDAgbg0KMDAwMDA0MjIzNyAwMDAwMCBuDQowMDAwMDQyMjU1IDAwMDAwIG4NCnRyYWlsZXINCjw8L1NpemUgNS9JRFs8OTNEREQ1RjRBQjk1NTU2NTVFMUFFQkU3Mjc4OTFGNzQ+PDUyRUNGNjUzRTlDQTM4NDNBMEI2MTY0ODI1RkZENjJDPl0+Pg0Kc3RhcnR4cmVmDQoxMTYNCiUlRU9GDQo=', @@ -106,11 +107,7 @@ eg023IdvAuthentication.createController = async (req, res) => { let signer1Tabs = new docusign.Tabs() signer1Tabs.signHereTabs = [signHere1]; -<<<<<<< HEAD -======= - ->>>>>>> 24fa985a2835666796fd3cd8720464ed5dcb9898 let signer1 = docusign.Signer.constructFromObject({ email: body.signerEmail, name: body.signerName, @@ -118,19 +115,11 @@ eg023IdvAuthentication.createController = async (req, res) => { routingOrder: '1', deliveryMethod: "Email", tabs: signer1Tabs, -<<<<<<< HEAD identityVerification: {'workflowId':workflowId, 'steps': null} }); // Add the recipient to the envelope object -======= - identityVerification: {'workflowId':workflowId, 'steps': null} - }); - - // Add the recipient to the envelope object - ->>>>>>> 24fa985a2835666796fd3cd8720464ed5dcb9898 let recipients = docusign.Recipients.constructFromObject({ signers: [signer1]}); env.recipients = recipients; diff --git a/lib/examples/eg024CreatePermission.js b/lib/examples/eg024CreatePermission.js index 5c93aaa4..c8a8d93e 100644 --- a/lib/examples/eg024CreatePermission.js +++ b/lib/examples/eg024CreatePermission.js @@ -7,7 +7,7 @@ const path = require('path') , docusign = require('docusign-esign') , validator = require('validator') - , dsConfig = require('../../ds_configuration.js').config + , dsConfig = require('../../config/index.js').config ; const eg024CreatePermission = exports diff --git a/lib/examples/eg031BulkSendEnvelopes.js b/lib/examples/eg031BulkSendEnvelopes.js index e271fff7..83c2f280 100644 --- a/lib/examples/eg031BulkSendEnvelopes.js +++ b/lib/examples/eg031BulkSendEnvelopes.js @@ -110,6 +110,7 @@ eg031BulkSendEnvelopes.createController = async (req, res) => { ] } }) + // Step 4. Create the draft envelope let envelope = await envelopeApi.createEnvelope(args.accountId, { diff --git a/package.json b/package.json index 0c3880ed..daf71fee 100644 --- a/package.json +++ b/package.json @@ -15,14 +15,14 @@ }, "repository": { "type": "git", - "url": "https://github.com/docusign/code-examples-node" + "url": "https://github.com/docusign/code-examples-nodejs" }, "author": "DocuSign, Inc", "license": "MIT", "bugs": { - "url": "https://github.com/docusign/code-examples-node/issues" + "url": "https://github.com/docusign/code-examples-nodejs/issues" }, - "homepage": "https://github.com/docusign/code-examples-node#readme", + "homepage": "https://github.com/docusign/code-examples-nodejs#readme", "engines": { "node": ">=8.10" }, @@ -37,7 +37,7 @@ "express-session": "^1.16.2", "fs": "0.0.1-security", "fs-extra": "^6.0.1", - "helmet": "^3.22.0", + "helmet": "^3.18.0", "jsonwebtoken": "^8.5.1", "memorystore": "^1.6.1", "moment": "^2.24.0", @@ -51,6 +51,6 @@ }, "devDependencies": { "chai": "^4.2.0", - "mocha": "^7.1.2" + "mocha": "^5.0.4" } } diff --git a/views/pages/examples/eg026PermissionChangeSingleSetting.ejs b/views/pages/examples/eg026PermissionChangeSingleSetting.ejs index 96c7a75f..6be38c9c 100644 --- a/views/pages/examples/eg026PermissionChangeSingleSetting.ejs +++ b/views/pages/examples/eg026PermissionChangeSingleSetting.ejs @@ -27,7 +27,7 @@
    - +
    Allow sequential signing
    diff --git a/views/pages/index_examples.ejs b/views/pages/index_examples.ejs index 64649b88..068fb771 100644 --- a/views/pages/index_examples.ejs +++ b/views/pages/index_examples.ejs @@ -1,5 +1,5 @@ <% if (showDoc) { %> -

    Documentation on using OAuth Authorization Code Grant from a Node Express application.

    +

    Documentation on using OAuth Authorization Code Grant and JWT from a Node Express application.

    <% } %> <% if (locals.dsConfig.multiSourceChooser) { %> diff --git a/views/pages/index_launchers.ejs b/views/pages/index_launchers.ejs index 20c0abb0..7f26ba55 100644 --- a/views/pages/index_launchers.ejs +++ b/views/pages/index_launchers.ejs @@ -1,6 +1,6 @@

    Launchers for the code examples

    -

    C#

    +

    C#

    The C# launcher is a ready to use Visual Studio solution. It uses the .NET Core MVC web framework. The launcher's C# code examples can be used @@ -8,25 +8,25 @@ authentication flow.

    -

    PHP

    +

    PHP

    The PHP launcher is a ready to use integration. The launcher's PHP code examples can be used with any web server that supports PHP. The examples can be used with the Authorization Code Grant or JWT authentication flow.

    -

    Java

    +

    Java

    The Java launcher is a ready to use integration. It uses the Spring Boot web framework. The launcher's code examples can be used with the Authorization Code Grant or JWT authentication flow.

    -

    Node.js

    +

    Node.js

    The Node launcher is a ready to use integration. It uses the Express web framework. The launcher's code examples can be used with the Authorization Code Grant or JWT authentication flow.

    -

    Curl (API)

    +

    Python

    +

    Python

    The Python 3 launcher is a ready to use integration. It uses the Flask web framework. The launcher's code examples can be used with the Authorization Code Grant or JWT authentication flow.