Search code examples
node.jsdocusignapidocusign-sdk

DocuSign: token from requestJWTApplicationToken returns 401 AUTHORIZATION_INVALID_TOKEN when createEnvelope is called


I have the following setup to get the access token:

import * as docusign from 'docusign-esign';

const expiresIn = 28800;

export const createClient = async (): Promise<docusign.ApiClient> => {
  const apiClient = new docusign.ApiClient({ basePath: process.env.BASE_PATH, oAuthBasePath: process.env.O_AUTH_BASE_PATH });

  try {
    const response = await apiClient.requestJWTApplicationToken(
      process.env.CLIENT_ID,
      ["signature", "impersonation"],
      Buffer.from(process.env.RSA_PRIVATE_KEY.replace(/\\n/g, '\n')),
      expiresIn
    );

    console.log(response.body.access_token) // -> successfully returns access token

    apiClient.addDefaultHeader("Authorization", "Bearer " + response.body.access_token);
  } catch (error){ throw AppError("My custom error") }

  return apiClient;
}

Then in another place I have the following function that is supposed to create an envelope:

import { EnvelopeDefinition, EnvelopeRecipients, EnvelopesApi, Signer } from 'docusign-esign';
import { createClient } from "./above-file-path.ts";

export const someFunction = async () => {
  const signer1: Signer = { email: '[email protected]', name: 'my name', roleName: 'my name' };
  const signer2: Signer = { email: '[email protected]', name: 'client name', roleName: 'Client' };

  const recipients: EnvelopeRecipients = { signers: [signer1, signer2] };

  const dsApiClient = await createClient();

  const envelope: EnvelopeDefinition = {
    emailSubject: 'Please sign this agreement',
    templateId: 'uuid-of-my-template',
    status: 'created',
    recipients,
  };

  const envelopesApi = new EnvelopesApi(dsApiClient);

  try {
    const { envelopeId, errorDetails } = await envelopesApi.createEnvelope(process.env.ACCOUNT_ID, {
      envelopeDefinition: envelope,
    });

    console.log("Success?: ", envelopeId)
  } catch (error) {
    console.log(error) // -> This gives: Unauthorized...{"errorCode":"AUTHORIZATION_INVALID_TOKEN","message":"The access token provided is expired, revoked or malformed. Authentication for System Application failed."}
  }
}

I keep getting the AUTHORIZATION_INVALID_TOKEN error.

Additional Notes:

  • I am calling this function immediately after I receive the token so I know it hasn't expired.
  • I am using the account-d.docusign.com for O_AUTH_BASE_PATH and https://demo.docusign.net/restapi for BASE_PATH.

Solution

  • Took me a second but I get what's happening. You're fetching a JWT Application Token which only works on certain Admin API endpoints. What you need is the requestJwtUserToken() function. Take a look at this page for how the user token method works. It essentially takes just one more argument which is the userId of the user being impersonated. Give that a try.