@@ -42,6 +42,7 @@ function isValidTriggerUrl(url) {
title={textContent.pageTitles.completeWorkflow}
behindTheScenesComponent={
}
backRoute={ROUTE.TRIGGER}
+ backText={textContent.buttons.backToWorkflows}
/>
@@ -62,6 +63,7 @@ function isValidTriggerUrl(url) {
title={textContent.pageTitles.triggerWorkflow}
behindTheScenesComponent={}
backRoute={ROUTE.TRIGGER}
+ backText={textContent.buttons.backToWorkflows}
/>
diff --git a/server/api/apiFactory.js b/server/api/apiFactory.js
deleted file mode 100644
index 759facd..0000000
--- a/server/api/apiFactory.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const configureInterceptors = (api, accessToken) => {
- // Request interceptor for API calls
- api.interceptors.request.use(
- async config => {
- config.headers = {
- Accept: 'application/json',
- 'Content-Type': 'application/json',
- };
- config.headers.Authorization = `Bearer ${accessToken}`;
- return config;
- },
- error => {
- Promise.reject(error);
- }
- );
-
- api.interceptors.response.use(
- response => response,
- error => {
- // eslint-disable-next-line no-console
- console.error(`API call failed. Error: ${error}`);
- return Promise.reject(error);
- }
- );
- return api;
-};
-
-const createAPI = (axios, accessToken) => {
- const api = configureInterceptors(
- axios.create({
- withCredentials: false,
- }),
- accessToken
- );
- return api;
-};
-
-const createMaestroApi = (axios, basePath, accountId, accessToken) => {
- const api = createAPI(axios, accessToken);
-
- const getWorkflowDefinitions = async params => {
- const response = await api.get(`${basePath}/accounts/${accountId}/workflows`, { params });
- return response.data;
- };
-
- const getTriggerRequirements = async workflowId => {
- const response = await api.get(`${basePath}/accounts/${accountId}/workflows/${workflowId}/trigger-requirements`);
- return response.data;
- };
-
- const triggerWorkflow = async (args, triggerUrl) => {
- const response = await api.post(triggerUrl, args);
- return response.data;
- };
-
- return {
- getWorkflowDefinitions,
- getTriggerRequirements,
- triggerWorkflow,
- };
-};
-
-module.exports = { createMaestroApi };
diff --git a/server/api/index.js b/server/api/index.js
deleted file mode 100644
index 1b6ac16..0000000
--- a/server/api/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-const axios = require('axios');
-const { createMaestroApi } = require('./apiFactory');
-
-const initMaestroApi = (accountId, basePath, accessToken) => createMaestroApi(axios, basePath, accountId, accessToken);
-
-module.exports = { initMaestroApi };
diff --git a/server/constants.js b/server/constants.js
index f82a176..05986eb 100644
--- a/server/constants.js
+++ b/server/constants.js
@@ -18,7 +18,7 @@ const ISSUES = {
TRIGGER_ISSUE: 'Incompatible workflow',
};
-const MAESTRO_SCOPES = ['signature', 'aow_manage', 'impersonation'];
+const MAESTRO_SCOPES = ['signature', 'aow_manage'];
module.exports = {
scopes: MAESTRO_SCOPES,
diff --git a/server/controllers/workflowsController.js b/server/controllers/workflowsController.js
index c8ee2c0..8f2bf79 100644
--- a/server/controllers/workflowsController.js
+++ b/server/controllers/workflowsController.js
@@ -83,11 +83,72 @@ class WorkflowsController {
}
};
+ static pauseWorkflow = async (req, res) => {
+ try {
+ const args = {
+ workflowId: req.params.definitionId,
+ accessToken: req?.user?.accessToken || req?.session?.accessToken,
+ accountId: req.session.accountId,
+ };
+
+ const result = await WorkflowsService.pauseWorkflow(args);
+ res.status(200).send(result);
+ } catch (error) {
+ this.handleErrorResponse(error, res);
+ }
+ };
+
+ static resumePausedWorkflow = async (req, res) => {
+ try {
+ const args = {
+ workflowId: req.params.definitionId,
+ accessToken: req?.user?.accessToken || req?.session?.accessToken,
+ accountId: req.session.accountId,
+ };
+
+ const result = await WorkflowsService.resumePausedWorkflow(args);
+ res.status(200).send(result);
+ } catch (error) {
+ this.handleErrorResponse(error, res);
+ }
+ };
+
+ static getInstances = async (req, res) => {
+ try {
+ const args = {
+ workflowId: req.params.definitionId,
+ accessToken: req?.user?.accessToken || req?.session?.accessToken,
+ accountId: req.session.accountId,
+ };
+
+ const result = await WorkflowsService.getInstances(args);
+ res.status(200).send(result);
+ } catch (error) {
+ this.handleErrorResponse(error, res);
+ }
+ };
+
+ static cancelWorkflow = async (req, res) => {
+ try {
+ const args = {
+ workflowId: req.params.definitionId,
+ instanceId: req.params.instanceId,
+ accessToken: req?.user?.accessToken || req?.session?.accessToken,
+ accountId: req.session.accountId,
+ };
+
+ const result = await WorkflowsService.cancelWorkflow(args);
+ res.status(200).send(result);
+ } catch (error) {
+ this.handleErrorResponse(error, res);
+ }
+ };
+
static handleErrorResponse(error, res) {
this.logger.error(`handleErrorResponse: ${error}`);
- const errorCode = error?.response?.statusCode;
- const errorMessage = error?.response?.body?.message;
+ const errorCode = error?.response?.statusCode || error?.statusCode;
+ const errorMessage = error?.response?.body?.message || error?.message || error?.rawMessage;
// use custom error message if Maestro is not enabled for the account
if (errorCode === 403) {
diff --git a/server/package-lock.json b/server/package-lock.json
index 44ce19b..887722a 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -8,6 +8,7 @@
"name": "server",
"version": "1.0.0",
"dependencies": {
+ "@docusign/iam-sdk": "1.0.0-beta.3",
"axios": "^1.7.7",
"body-parser": "^1.20.3",
"chalk": "^4.1.2",
@@ -62,6 +63,14 @@
"resolved": "https://registry.npmjs.org/@devhigley/parse-proxy/-/parse-proxy-1.0.3.tgz",
"integrity": "sha512-ozRQ9CgWF4JXNNae1zUEpb2fbqH61oxtZz2sdR7a0ci5mi9pSP3EvoU7g4idZYi+CXP32gsvH7kTYZJCGW3DKQ=="
},
+ "node_modules/@docusign/iam-sdk": {
+ "version": "1.0.0-beta.3",
+ "resolved": "https://registry.npmjs.org/@docusign/iam-sdk/-/iam-sdk-1.0.0-beta.3.tgz",
+ "integrity": "sha512-kK3lftOtfc+smFcmjURy9XHwhFQ1aXFj+hpRnWjLWl5juXi5/J79xILJVasJyX25T4GEvJP1946BgfpllNn9xg==",
+ "peerDependencies": {
+ "zod": ">= 3"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
@@ -4758,6 +4767,15 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zod": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.0.10.tgz",
+ "integrity": "sha512-3vB+UU3/VmLL2lvwcY/4RV2i9z/YU0DTV/tDuYjrwmx5WeJ7hwy+rGEEx8glHp6Yxw7ibRbKSaIFBgReRPe5KA==",
+ "peer": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
}
}
}
diff --git a/server/package.json b/server/package.json
index c9370dd..f0700fa 100644
--- a/server/package.json
+++ b/server/package.json
@@ -11,6 +11,7 @@
},
"author": "",
"dependencies": {
+ "@docusign/iam-sdk": "1.0.0-beta.3",
"axios": "^1.7.7",
"body-parser": "^1.20.3",
"chalk": "^4.1.2",
diff --git a/server/routes/workflowsRouter.js b/server/routes/workflowsRouter.js
index 080cd0a..a32635a 100644
--- a/server/routes/workflowsRouter.js
+++ b/server/routes/workflowsRouter.js
@@ -5,6 +5,10 @@ const authMiddleware = require('../middlewares/authMiddleware');
const router = Router();
router.put('/:definitionId/trigger', authMiddleware, workflowsController.triggerWorkflow);
+router.post('/:definitionId/pause', authMiddleware, workflowsController.pauseWorkflow);
+router.post('/:definitionId/resume', authMiddleware, workflowsController.resumePausedWorkflow);
+router.get('/:definitionId/instances', authMiddleware, workflowsController.getInstances);
+router.post('/:definitionId/instances/:instanceId/cancel', authMiddleware, workflowsController.cancelWorkflow);
router.get('/definitions', authMiddleware, workflowsController.getWorkflowDefinitions);
router.get('/:definitionId/requirements', authMiddleware, workflowsController.getWorkflowTriggerRequirements);
diff --git a/server/services/workflowsService.js b/server/services/workflowsService.js
index 544823f..34eb6f4 100644
--- a/server/services/workflowsService.js
+++ b/server/services/workflowsService.js
@@ -2,40 +2,82 @@
* @file
* This file handles work with docusign maestro and esign services.
* Scenarios implemented:
- * - Workflow definition creation.
- * - Workflow definition publishing.
* - Workflow definition triggering, which create workflow instance.
- * - Workflow instance cancellation.
- * - Workflow instance fetching.
+ * - Workflow definitions fetching.
+ * - Workflow trigger requirements fetching.
*/
-const { initMaestroApi } = require('../api');
+const iam = require('@docusign/iam-sdk');
class WorkflowsService {
static getWorkflowDefinitions = async args => {
- const api = initMaestroApi(args.accountId, args.basePath, args.accessToken);
- const definitions = await api.getWorkflowDefinitions({});
+ const client = new iam.IamClient({ accessToken: args.accessToken });
+ const definitions = await client.maestro.workflows.getWorkflowsList({ accountId: args.accountId });
return definitions;
};
static getWorkflowTriggerRequirements = async args => {
- const api = initMaestroApi(args.accountId, args.basePath, args.accessToken);
- const triggerRequirements = await api.getTriggerRequirements(args.workflowId);
+ const client = new iam.IamClient({ accessToken: args.accessToken });
+ const triggerRequirements = await client.maestro.workflows.getWorkflowTriggerRequirements({
+ accountId: args.accountId,
+ workflowId: args.workflowId,
+ });
return triggerRequirements;
};
- static triggerWorkflowInstance = async (args, payload, triggerRequirements) => {
- const api = initMaestroApi(args.accountId, args.basePath, args.accessToken);
+ static triggerWorkflowInstance = async (args, payload) => {
+ const client = new iam.IamClient({ accessToken: args.accessToken });
const triggerPayload = {
instance_name: 'test',
trigger_inputs: payload,
};
- const triggerResponse = await api.triggerWorkflow(triggerPayload, triggerRequirements.trigger_http_config.url);
+ const triggerResponse = await client.maestro.workflows.triggerWorkflow({
+ accountId: args.accountId,
+ workflowId: args.workflowId,
+ triggerWorkflow: triggerPayload,
+ });
return triggerResponse;
};
+
+ static pauseWorkflow = async args => {
+ const client = new iam.IamClient({ accessToken: args.accessToken });
+
+ return await client.maestro.workflows.pauseNewWorkflowInstances({
+ accountId: args.accountId,
+ workflowId: args.workflowId,
+ });
+ };
+
+ static resumePausedWorkflow = async args => {
+ const client = new iam.IamClient({ accessToken: args.accessToken });
+
+ return await client.maestro.workflows.resumePausedWorkflow({
+ accountId: args.accountId,
+ workflowId: args.workflowId,
+ });
+ };
+
+ static getInstances = async args => {
+ const client = new iam.IamClient({ accessToken: args.accessToken });
+
+ return await client.maestro.workflowInstanceManagement.getWorkflowInstancesList({
+ accountId: args.accountId,
+ workflowId: args.workflowId,
+ });
+ };
+
+ static cancelWorkflow = async args => {
+ const client = new iam.IamClient({ accessToken: args.accessToken });
+
+ return await client.maestro.workflowInstanceManagement.cancelWorkflowInstance({
+ accountId: args.accountId,
+ workflowId: args.workflowId,
+ instanceId: args.instanceId,
+ });
+ };
}
module.exports = WorkflowsService;