Skip to content

Commit a25223b

Browse files
author
nianiB9
authored
Merge pull request #207 from docusign/feature/connected-fields
Add Connected fields example
2 parents a93c6cf + e8abb08 commit a25223b

File tree

9 files changed

+413
-4
lines changed

9 files changed

+413
-4
lines changed

index.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ const {
5858
const { eg001connect } = require('./lib/connect/controllers');
5959
const { eg001webforms } = require('./lib/webforms/controllers');
6060
const { eg004notary } = require('./lib/notary/controllers');
61+
const { eg001fields } = require('./lib/connectedFields/controllers');
6162

6263
const PORT = process.env.PORT || 3000;
6364
const HOST = process.env.HOST || 'localhost';
@@ -286,8 +287,11 @@ app.get('/weg001', eg001webforms.getController)
286287
.post('/weg001', eg001webforms.createWebFormTemplate)
287288
.post('/weg001webForm', eg001webforms.createWebFormInstance);
288289

289-
app.get('/neg004', eg004notary.getController)
290-
.post('/neg004', eg004notary.createController)
290+
app.get('/neg004', eg004notary.getController)
291+
.post('/neg004', eg004notary.createController);
292+
293+
app.get('/feg001', eg001fields.getController)
294+
.post('/feg001', eg001fields.createController);
291295

292296

293297
function dsLoginCB1(req, res, next) { req.dsAuthCodeGrant.oauth_callback1(req, res, next); }
@@ -340,8 +344,20 @@ const WEBFORMS_SCOPES = [
340344
const NOTARY_SCOPES = [
341345
'signature', 'organization_read', 'notary_read', 'notary_write'
342346
];
347+
const CONNECTED_FIELDS_SCOPES = [
348+
'signature', 'adm_store_unified_repo_read'
349+
];
343350

344-
const scope = [...ROOM_SCOPES, ...CLICK_SCOPES, ...MONITOR_SCOPES, ...ADMIN_SCOPES, ...SCOPES, ...WEBFORMS_SCOPES, ...NOTARY_SCOPES];
351+
const scope = [
352+
...ROOM_SCOPES,
353+
...CLICK_SCOPES,
354+
...MONITOR_SCOPES,
355+
...ADMIN_SCOPES,
356+
...SCOPES,
357+
...WEBFORMS_SCOPES,
358+
...NOTARY_SCOPES,
359+
...CONNECTED_FIELDS_SCOPES,
360+
];
345361

346362
// Configure passport for DocusignStrategy
347363
const docusignStrategyOptions = {

lib/DSJwtAuth.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ let DsJwtAuth = function _DsJwtAuth(req) {
1818
this.accountName = req.user && req.user.accountName;
1919
this.basePath = req.user && req.user.basePath;
2020
this._tokenExpiration = req.user && req.user.tokenExpirationTimestamp;
21-
this.scopes = 'signature dtr.rooms.read dtr.rooms.write dtr.documents.read dtr.documents.write dtr.profile.read dtr.profile.write dtr.company.read dtr.company.write room_forms click.manage click.send organization_read group_read permission_read user_read user_write account_read domain_read identity_provider_read user_data_redact asset_group_account_read asset_group_account_clone_write asset_group_account_clone_read webforms_read webforms_instance_read webforms_instance_write aow_manage organization_sub_account_write organization_sub_account_read';
21+
this.scopes = 'signature dtr.rooms.read dtr.rooms.write dtr.documents.read dtr.documents.write dtr.profile.read dtr.profile.write dtr.company.read dtr.company.write room_forms click.manage click.send organization_read group_read permission_read user_read user_write account_read domain_read identity_provider_read user_data_redact asset_group_account_read asset_group_account_clone_write asset_group_account_clone_read webforms_read webforms_instance_read webforms_instance_write aow_manage organization_sub_account_write organization_sub_account_read adm_store_unified_repo_read';
2222
this.eg = req.session.eg;
2323

2424
// For production use, you'd want to store the refresh token in non-volatile storage since it is
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/**
2+
* @file
3+
* Example 001: Set connected fields
4+
* @author DocuSign
5+
*/
6+
7+
const path = require('path');
8+
const { getTabGroups, sendEnvelope, extractVerificationData } = require('../examples/setConnectedFields');
9+
const validator = require('validator');
10+
const { getExampleByNumber } = require('../../manifestService');
11+
const dsConfig = require('../../../config/index.js').config;
12+
const { API_TYPES } = require('../../utils.js');
13+
14+
const eg001SetConnectedFields = exports;
15+
const exampleNumber = 1;
16+
const eg = `feg00${exampleNumber}`; // This example reference.
17+
const api = API_TYPES.CONNECTED_FIELDS;
18+
const mustAuthenticate = '/ds/mustAuthenticate';
19+
const minimumBufferMin = 3;
20+
const demoDocsPath = path.resolve(__dirname, '../../../demo_documents');
21+
const pdfFile = 'World_Wide_Corp_lorem.pdf';
22+
23+
/**
24+
* Create the envelope, the embedded signing, and then redirect to the DocuSign signing
25+
* @param {object} req Request obj
26+
* @param {object} res Response obj
27+
*/
28+
eg001SetConnectedFields.createController = async (req, res) => {
29+
// Step 1. Check the token
30+
// At this point we should have a good token. But we
31+
// double-check here to enable a better UX to the user.
32+
const isTokenOK = req.dsAuth.checkToken(minimumBufferMin);
33+
if (!isTokenOK) {
34+
req.flash('info', 'Sorry, you need to re-authenticate.');
35+
// Save the current operation so it will be resumed after authentication
36+
req.dsAuth.setEg(req, eg);
37+
return res.redirect(mustAuthenticate);
38+
}
39+
40+
// Step 2. Call the worker method
41+
const { body } = req;
42+
const selectedAppId = validator.escape(body.appId);
43+
const verificationData = extractVerificationData(selectedAppId, req.session.apps);
44+
const envelopeArgs = {
45+
signerEmail: validator.escape(body.signerEmail),
46+
signerName: validator.escape(body.signerName),
47+
docFile: path.resolve(demoDocsPath, pdfFile),
48+
verificationData
49+
};
50+
const args = {
51+
accessToken: req.user.accessToken,
52+
basePath: req.session.basePath,
53+
accountId: req.session.accountId,
54+
envelopeArgs: envelopeArgs,
55+
};
56+
57+
let results = null;
58+
try {
59+
results = await sendEnvelope(args);
60+
} catch (error) {
61+
const errorBody = error && error.response && error.response.body;
62+
// we can pull the DocuSign error code and message from the response body
63+
const errorCode = errorBody && errorBody.errorCode;
64+
const errorMessage = errorBody && errorBody.message;
65+
// In production, may want to provide customized error messages and
66+
// remediation advice to the user.
67+
res.render('pages/error', { err: error, errorCode, errorMessage });
68+
}
69+
if (results) {
70+
req.session.envelopeId = results.envelopeId; // Save for use by other examples
71+
// which need an envelopeId
72+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
73+
res.render('pages/example_done', {
74+
title: example.ExampleName,
75+
message: formatString(example.ResultsPageText, results.envelopeId),
76+
});
77+
}
78+
};
79+
80+
/**
81+
* Form page for this application
82+
*/
83+
eg001SetConnectedFields.getController = async (req, res) => {
84+
// Check that the authentication token is ok with a long buffer time.
85+
// If needed, now is the best time to ask the user to authenticate
86+
// since they have not yet entered any information into the form.
87+
const isTokenOK = req.dsAuth.checkToken();
88+
if (!isTokenOK) {
89+
// Save the current operation so it will be resumed after authentication
90+
req.dsAuth.setEg(req, eg);
91+
return res.redirect(mustAuthenticate);
92+
}
93+
94+
const args = {
95+
accessToken: req.user.accessToken,
96+
basePath: 'https://api-d.docusign.com',
97+
accountId: req.session.accountId,
98+
};
99+
const tabGroups = await getTabGroups(args);
100+
101+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
102+
if (tabGroups.length === 0) {
103+
const additionalPageData = example.AdditionalPage.filter(p => p.Name === 'no_verification_app')[0];
104+
105+
return res.render('pages/example_done', {
106+
title: example.ExampleName,
107+
message: additionalPageData?.ResultsPageText,
108+
});
109+
}
110+
req.session.apps = tabGroups;
111+
112+
const sourceFile =
113+
path.basename(__filename)[5].toLowerCase() +
114+
path.basename(__filename).substr(6);
115+
res.render('pages/connected-fields/eg001SetConnectedFields', {
116+
eg: eg,
117+
csrfToken: req.csrfToken(),
118+
example: example,
119+
sourceFile: sourceFile,
120+
sourceUrl: dsConfig.githubExampleUrl + 'connectedFields/examples/' + sourceFile,
121+
documentation: dsConfig.documentation + eg,
122+
showDoc: dsConfig.documentation,
123+
apps: tabGroups,
124+
});
125+
126+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports.eg001fields = require('./eg001SetConnectedFields');

0 commit comments

Comments
 (0)