ml-testing-toolkit 18.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/.dockerignore +10 -0
  2. package/.grype.yaml +16 -0
  3. package/.ncurc.yaml +9 -0
  4. package/.nvmrc +1 -0
  5. package/.versionrc.js +16 -0
  6. package/CHANGELOG.md +504 -0
  7. package/CODEOWNERS +30 -0
  8. package/Dockerfile +42 -0
  9. package/Dockerfile-newman +13 -0
  10. package/LICENSE.md +9 -0
  11. package/README.md +119 -0
  12. package/assets/diagrams/architectural/architectural-diagram.svg +3 -0
  13. package/assets/diagrams/flow/flow-diagram.svg +3 -0
  14. package/assets/images/Sample-Response-Failure.png +0 -0
  15. package/assets/images/Screenshot 2020-04-16 at 22.58.04.png +0 -0
  16. package/assets/images/TLS-Enabled-on-Environment.png +0 -0
  17. package/assets/images/adapter-mutual-tls-enabled.png +0 -0
  18. package/assets/images/add-additional-input-values.png +0 -0
  19. package/assets/images/add-condition-button.png +0 -0
  20. package/assets/images/add-new-assertion.png +0 -0
  21. package/assets/images/add-new-input-value.png +0 -0
  22. package/assets/images/add-new-input-variable.png +0 -0
  23. package/assets/images/additional-transfers.png +0 -0
  24. package/assets/images/api-provisioning-add-new-api-confirmation.png +0 -0
  25. package/assets/images/api-provisioning-file-input-window.png +0 -0
  26. package/assets/images/api-provisioning-list-apis-view.png +0 -0
  27. package/assets/images/api-provisioning-menu-item.png +0 -0
  28. package/assets/images/apply_and_restart.jpg +0 -0
  29. package/assets/images/assess-request-or-response.png +0 -0
  30. package/assets/images/assess-response-equation-save.png +0 -0
  31. package/assets/images/assess-response-equation.png +0 -0
  32. package/assets/images/assess-response-status.png +0 -0
  33. package/assets/images/building-new-rules-file.png +0 -0
  34. package/assets/images/callback-rules-screen.png +0 -0
  35. package/assets/images/configurable-parameter-assertion.png +0 -0
  36. package/assets/images/configurable-parameter-currency.png +0 -0
  37. package/assets/images/configurable-parameter.png +0 -0
  38. package/assets/images/connection-manager-ui-opening.png +0 -0
  39. package/assets/images/create-inbound-user-simulator.png +0 -0
  40. package/assets/images/creating-new-rule-file.png +0 -0
  41. package/assets/images/dfsp-client-cacert.png +0 -0
  42. package/assets/images/dfsp-client-submit.png +0 -0
  43. package/assets/images/dfsp-client.png +0 -0
  44. package/assets/images/dfsp-p2p-happy-path.png +0 -0
  45. package/assets/images/dfsp-server-cacert.png +0 -0
  46. package/assets/images/dfsp-server-cert.png +0 -0
  47. package/assets/images/download-report.png +0 -0
  48. package/assets/images/drive_have_not_been_shared.jpg +0 -0
  49. package/assets/images/event-response-options.png +0 -0
  50. package/assets/images/expand-monitoring-messages.png +0 -0
  51. package/assets/images/fixed-response-sample.png +0 -0
  52. package/assets/images/header-selection.png +0 -0
  53. package/assets/images/heap_error_windows.jpg +0 -0
  54. package/assets/images/hosted-mode-docker-compose-intro.png +0 -0
  55. package/assets/images/hub-client-cert.png +0 -0
  56. package/assets/images/import-template.png +0 -0
  57. package/assets/images/inbound-requests-environment.png +0 -0
  58. package/assets/images/inbound-requests-scripts.png +0 -0
  59. package/assets/images/jws-certificate-submit.png +0 -0
  60. package/assets/images/jws-certificate.png +0 -0
  61. package/assets/images/jws-certs-keys.png +0 -0
  62. package/assets/images/jws-hub-certs-keys.png +0 -0
  63. package/assets/images/local-enable-jws-publickey.png +0 -0
  64. package/assets/images/local-mutual-tls-enabled.png +0 -0
  65. package/assets/images/local_drives_to_be_available.jpg +0 -0
  66. package/assets/images/mcm-environment-opening.png +0 -0
  67. package/assets/images/menu-items.png +0 -0
  68. package/assets/images/mock-response-sample.png +0 -0
  69. package/assets/images/monitoring-initial-state.png +0 -0
  70. package/assets/images/monitoring-messages.png +0 -0
  71. package/assets/images/new-empty-assertion.png +0 -0
  72. package/assets/images/opened-imported-template.png +0 -0
  73. package/assets/images/opening-default-settings.png +0 -0
  74. package/assets/images/opening-sync-response-rules.png +0 -0
  75. package/assets/images/opening-view.png +0 -0
  76. package/assets/images/outbound-display-opening-hub.png +0 -0
  77. package/assets/images/outbound-display-opening.png +0 -0
  78. package/assets/images/override-with-environment-variable.png +0 -0
  79. package/assets/images/populate-with-sample-body.png +0 -0
  80. package/assets/images/resource-selection.png +0 -0
  81. package/assets/images/rule-builder-select-api.png +0 -0
  82. package/assets/images/sample-condition-add-configurable-params.png +0 -0
  83. package/assets/images/sample-condition.png +0 -0
  84. package/assets/images/sample-editor.png +0 -0
  85. package/assets/images/sample-request.png +0 -0
  86. package/assets/images/sample-test-assertion.png +0 -0
  87. package/assets/images/send-transfer.png +0 -0
  88. package/assets/images/sending-single-test-case-1.png +0 -0
  89. package/assets/images/sending-single-test-case-2.png +0 -0
  90. package/assets/images/sending-test-cases.png +0 -0
  91. package/assets/images/server-certificates-submitted.png +0 -0
  92. package/assets/images/simulator-response.png +0 -0
  93. package/assets/images/simulator-scheme-adapter-endpoint.png +0 -0
  94. package/assets/images/summarized-view-of-rule.png +0 -0
  95. package/assets/images/template-window.png +0 -0
  96. package/assets/images/test-case-editor-console-log.png +0 -0
  97. package/assets/images/test-case-editor-environment-state.png +0 -0
  98. package/assets/images/test-case-editor-scripts.png +0 -0
  99. package/assets/images/test-case-editor.png +0 -0
  100. package/assets/images/testcase-definition-download.png +0 -0
  101. package/assets/images/testcase-definition-edit-meta-info.png +0 -0
  102. package/assets/images/testing-toolkit-mojaloop-testing-toolkit-endpoint.png +0 -0
  103. package/assets/images/tls-hub-certs-keys.png +0 -0
  104. package/assets/images/tls-jws-enabled-on-environment.png +0 -0
  105. package/assets/images/updated-sample-body-data.png +0 -0
  106. package/assets/images/using-configurable-parameter.png +0 -0
  107. package/assets/images/validation-rules-screen.png +0 -0
  108. package/assets/images/view-response.png +0 -0
  109. package/audit-ci.jsonc +7 -0
  110. package/connection-manager/docker-compose.yml +55 -0
  111. package/database/docker-compose.yml +16 -0
  112. package/docker/hosted-mode/docker-compose.yaml +107 -0
  113. package/docker/hosted-mode/keycloak/keycloak-realm.json +2298 -0
  114. package/docker/hosted-mode/mongo-init.sh +1 -0
  115. package/docker/hosted-mode-tls/docker-compose.yaml +171 -0
  116. package/docker/hosted-mode-tls/keycloak/keycloak-realm.json +2298 -0
  117. package/docker/hosted-mode-tls/mongo-init.sh +1 -0
  118. package/docker-compose.yml +62 -0
  119. package/documents/Mojaloop-Testing-Toolkit.md +296 -0
  120. package/documents/RULES_ENGINE.md +403 -0
  121. package/documents/User-Guide-API-Provisioning.md +121 -0
  122. package/documents/User-Guide-CLI.md +218 -0
  123. package/documents/User-Guide-Connection-Manager.md +282 -0
  124. package/documents/User-Guide-Frequently-Asked-Questions.md +39 -0
  125. package/documents/User-Guide-Hosted-Mode-Docker-Compose.md +110 -0
  126. package/documents/User-Guide-Installation.md +163 -0
  127. package/documents/User-Guide-Mojaloop-Testing-Toolkit.md +642 -0
  128. package/documents/User-Guide-OAuth-Server-Deployment.md +283 -0
  129. package/documents/User-Guide-Onboarding-DFSP.md +197 -0
  130. package/documents/User-Guide-Onboarding-HUB.md +191 -0
  131. package/documents/User-Guide.md +53 -0
  132. package/examples/collections/dfsp/p2p_failed_tests.json +7161 -0
  133. package/examples/collections/dfsp/p2p_fx_happy_path.json +502 -0
  134. package/examples/collections/dfsp/p2p_happy_path.json +350 -0
  135. package/examples/collections/dfsp/p2p_happy_path_extended.json +6106 -0
  136. package/examples/collections/dfsp/p2p_happy_path_jws.json +511 -0
  137. package/examples/collections/dfsp/p2p_payee_assertions_websocket.json +441 -0
  138. package/examples/collections/dfsp/sample.json +5029 -0
  139. package/examples/collections/dfsp/transaction_request_service.json +240 -0
  140. package/examples/collections/fxp/FXP.json +264 -0
  141. package/examples/collections/fxp/SDK_backend.json +98 -0
  142. package/examples/collections/fxp/SDK_outbound.json +163 -0
  143. package/examples/collections/hub/hub_01_p2p_happy_path/hub_p2p_receive_quote.json +400 -0
  144. package/examples/collections/hub/hub_01_p2p_happy_path/hub_p2p_send_quote.json +395 -0
  145. package/examples/collections/hub/hub_02_block_transfer/hub_block_transfer.json +393 -0
  146. package/examples/collections/hub/hub_03_funds_in_out/hub_funds_in.json +224 -0
  147. package/examples/collections/hub/hub_03_funds_in_out/hub_funds_out.json +780 -0
  148. package/examples/collections/hub/hub_04_settlements/hub_settlements.json +3138 -0
  149. package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_payee_abort.json +475 -0
  150. package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_payee_invalid_fulfillment.json +370 -0
  151. package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_transfer_timeout.json +262 -0
  152. package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_authorizations.json +117 -0
  153. package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_error_framework.json +591 -0
  154. package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_received_state.json +379 -0
  155. package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_reject_state.json +361 -0
  156. package/examples/collections/hub/hub_07_quoting_service.json +525 -0
  157. package/examples/collections/hub/hub_08_participant_inactive_stop_transfers.json +706 -0
  158. package/examples/collections/hub/hub_09_duplicate_handling_transfers.json +1377 -0
  159. package/examples/collections/hub/hub_10_on_us_transfers.json +245 -0
  160. package/examples/collections/hub/hub_11_accented_and_spl_chars.json +629 -0
  161. package/examples/collections/hub/hub_12_fspiop_version_1.1.json +646 -0
  162. package/examples/collections/hub/hub_13_bulk_transfers.json +1857 -0
  163. package/examples/collections/iso20022/self_referencing_iso20022.json +926 -0
  164. package/examples/collections/provisioning/testingtoolkitdfsp.json +904 -0
  165. package/examples/environments/dfsp_local_environment.json +46 -0
  166. package/examples/environments/hub_local_environment.json +57 -0
  167. package/jest.config.js +17 -0
  168. package/package.json +199 -0
  169. package/sbom-v18.12.4.csv +1553 -0
  170. package/secrets/keygen.sh +5 -0
  171. package/secrets/privatekey.pem +27 -0
  172. package/secrets/publickey.cer +21 -0
  173. package/secrets/tls/01.pem +132 -0
  174. package/secrets/tls/createSecrets.sh +20 -0
  175. package/secrets/tls/hub_client.csr +32 -0
  176. package/secrets/tls/hub_client_cacert.pem +35 -0
  177. package/secrets/tls/hub_client_cakey.pem +52 -0
  178. package/secrets/tls/hub_client_key.key +52 -0
  179. package/secrets/tls/hub_server.csr +31 -0
  180. package/secrets/tls/hub_server_cacert.pem +35 -0
  181. package/secrets/tls/hub_server_cakey.pem +52 -0
  182. package/secrets/tls/hub_server_cert.pem +132 -0
  183. package/secrets/tls/hub_server_key.key +52 -0
  184. package/secrets/tls/index.txt +1 -0
  185. package/secrets/tls/index.txt.attr +1 -0
  186. package/secrets/tls/openssl-client.cnf +36 -0
  187. package/secrets/tls/openssl-clientca.cnf +71 -0
  188. package/secrets/tls/openssl-server.cnf +39 -0
  189. package/secrets/tls/openssl-serverca.cnf +71 -0
  190. package/secrets/tls/serial.txt +1 -0
  191. package/spec_files/api_definitions/als_admin_1.1/api_spec.yaml +804 -0
  192. package/spec_files/api_definitions/central_admin_1.0/api_spec.yaml +1850 -0
  193. package/spec_files/api_definitions/central_admin_1.0/response_map.json +96 -0
  194. package/spec_files/api_definitions/central_admin_old_9.3/api_spec.yaml +2467 -0
  195. package/spec_files/api_definitions/central_admin_old_9.3/response_map.json +96 -0
  196. package/spec_files/api_definitions/fspiop_1.0/api_spec.yaml +4187 -0
  197. package/spec_files/api_definitions/fspiop_1.0/callback_map.json +568 -0
  198. package/spec_files/api_definitions/fspiop_1.0/mockRef.json +79 -0
  199. package/spec_files/api_definitions/fspiop_1.0/trigger_templates/transaction_request_followup.json +126 -0
  200. package/spec_files/api_definitions/fspiop_1.0/trigger_templates/transaction_request_followup_quotes_only.json +97 -0
  201. package/spec_files/api_definitions/fspiop_1.1/api_spec.yaml +3778 -0
  202. package/spec_files/api_definitions/fspiop_1.1/callback_map.json +568 -0
  203. package/spec_files/api_definitions/fspiop_1.1/mockRef.json +79 -0
  204. package/spec_files/api_definitions/fspiop_1.1/trigger_templates/transaction_request_followup.json +125 -0
  205. package/spec_files/api_definitions/fspiop_2.0/api_spec.yaml +4839 -0
  206. package/spec_files/api_definitions/fspiop_2.0/callback_map.json +716 -0
  207. package/spec_files/api_definitions/fspiop_2.0/mockRef.json +79 -0
  208. package/spec_files/api_definitions/fspiop_2.0/trigger_templates/transaction_request_followup.json +125 -0
  209. package/spec_files/api_definitions/fspiop_2.0_iso20022/api_spec.yaml +8331 -0
  210. package/spec_files/api_definitions/fspiop_2.0_iso20022/callback_map.json +508 -0
  211. package/spec_files/api_definitions/fspiop_2.0_iso20022/mockRef.json +66 -0
  212. package/spec_files/api_definitions/fx-api_2.0/api_spec.yaml +1768 -0
  213. package/spec_files/api_definitions/fx-api_2.0/callback_map.json +188 -0
  214. package/spec_files/api_definitions/fx-api_2.0/mockRef.json +83 -0
  215. package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/api_spec.yaml +2612 -0
  216. package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/mockRef.json +22 -0
  217. package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/response_map.json +35 -0
  218. package/spec_files/api_definitions/mojaloop_simulator_0.1/api_spec.yaml +225 -0
  219. package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/api_spec.yaml +1087 -0
  220. package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/mockRef.json +75 -0
  221. package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/response_map.json +55 -0
  222. package/spec_files/api_definitions/payment_manager_1.4/api_spec.yaml +1389 -0
  223. package/spec_files/api_definitions/sdk-scheme-adapter-backend-v2_1_0-openapi3-snippets_2.1/api_spec.yaml +2834 -0
  224. package/spec_files/api_definitions/sdk-scheme-adapter-outbound-v2_1_0-openapi3-snippets_2.1/api_spec.yaml +3449 -0
  225. package/spec_files/api_definitions/settlements_1.0/api_spec.yaml +983 -0
  226. package/spec_files/api_definitions/settlements_1.0/mockRef.json +38 -0
  227. package/spec_files/api_definitions/settlements_1.0/response_map.json +34 -0
  228. package/spec_files/api_definitions/settlements_2.0/api_spec.yaml +1001 -0
  229. package/spec_files/api_definitions/settlements_2.0/mockRef.json +38 -0
  230. package/spec_files/api_definitions/settlements_2.0/response_map.json +34 -0
  231. package/spec_files/api_definitions/thirdparty_sdk_outbound_0.1/api_spec.yaml +2139 -0
  232. package/spec_files/reports/templates/newman/html_template.html +1202 -0
  233. package/spec_files/reports/templates/newman/pdf_template.html +790 -0
  234. package/spec_files/reports/templates/testcase_definition/table_view.html +1602 -0
  235. package/spec_files/rules_callback/config.json +3 -0
  236. package/spec_files/rules_callback/default.json +2698 -0
  237. package/spec_files/rules_callback/p2p-limit.json +129 -0
  238. package/spec_files/rules_forward/config.json +3 -0
  239. package/spec_files/rules_forward/default.json +482 -0
  240. package/spec_files/rules_response/config.json +3 -0
  241. package/spec_files/rules_response/default.json +295 -0
  242. package/spec_files/rules_validation/config.json +3 -0
  243. package/spec_files/rules_validation/default.json +1 -0
  244. package/spec_files/rules_validation/p2p-limit.json +55 -0
  245. package/spec_files/system_config.json +175 -0
  246. package/spec_files/user_config.json +109 -0
  247. package/src/index.js +67 -0
  248. package/src/lib/MyEventEmitter.js +54 -0
  249. package/src/lib/api-management.js +143 -0
  250. package/src/lib/api-routes/config.js +83 -0
  251. package/src/lib/api-routes/history.js +139 -0
  252. package/src/lib/api-routes/keycloak.js +54 -0
  253. package/src/lib/api-routes/longpolling.js +70 -0
  254. package/src/lib/api-routes/oauth2.js +149 -0
  255. package/src/lib/api-routes/objectstore.js +53 -0
  256. package/src/lib/api-routes/openapi.js +224 -0
  257. package/src/lib/api-routes/outbound.js +134 -0
  258. package/src/lib/api-routes/reports.js +72 -0
  259. package/src/lib/api-routes/rules.js +356 -0
  260. package/src/lib/api-routes/samples.js +92 -0
  261. package/src/lib/api-routes/server-logs.js +44 -0
  262. package/src/lib/api-routes/settings.js +71 -0
  263. package/src/lib/api-server.js +135 -0
  264. package/src/lib/arrayStore.js +101 -0
  265. package/src/lib/callbackHandler.js +201 -0
  266. package/src/lib/config.js +177 -0
  267. package/src/lib/configuration-providers/mb-connection-manager.js +625 -0
  268. package/src/lib/db/adapters/dbAdapter.js +184 -0
  269. package/src/lib/db/dfspMockUsers.js +64 -0
  270. package/src/lib/db/models/mongoDBWrapper.js +78 -0
  271. package/src/lib/eventListenerClient/inboundEventListener.js +176 -0
  272. package/src/lib/fileAdapter.js +57 -0
  273. package/src/lib/httpAgentStore.js +135 -0
  274. package/src/lib/importExport.js +186 -0
  275. package/src/lib/jws/JwsSigning.js +141 -0
  276. package/src/lib/loadSamples.js +128 -0
  277. package/src/lib/logger.js +20 -0
  278. package/src/lib/longpollingEmitter.js +56 -0
  279. package/src/lib/metrics.js +51 -0
  280. package/src/lib/mocking/custom-functions/generic.js +57 -0
  281. package/src/lib/mocking/middleware-functions/ilpModel.js +238 -0
  282. package/src/lib/mocking/middleware-functions/quotesAssociation.js +75 -0
  283. package/src/lib/mocking/middleware-functions/transactionRequestsService.js +78 -0
  284. package/src/lib/mocking/openApiDefinitionsModel.js +64 -0
  285. package/src/lib/mocking/openApiMockHandler.js +466 -0
  286. package/src/lib/mocking/openApiRulesEngine.js +492 -0
  287. package/src/lib/mocking/openApiVersionTools.js +136 -0
  288. package/src/lib/mocking/transformers/fspiopToISO20022.js +230 -0
  289. package/src/lib/mocking/transformers/index.js +41 -0
  290. package/src/lib/notificationEmitter.js +64 -0
  291. package/src/lib/oauth/KeycloakHelper.js +220 -0
  292. package/src/lib/oauth/LoginService.js +133 -0
  293. package/src/lib/oauth/OAuthHelper.js +181 -0
  294. package/src/lib/oauth/OAuthValidator.js +118 -0
  295. package/src/lib/oauth/Wso2Client.js +64 -0
  296. package/src/lib/objectStore/inMemoryImpl.js +50 -0
  297. package/src/lib/objectStore/objectStoreInterface.js +51 -0
  298. package/src/lib/objectStore.js +122 -0
  299. package/src/lib/report-generator/generator.js +126 -0
  300. package/src/lib/report-generator/helpers.js +154 -0
  301. package/src/lib/requestLogger.js +190 -0
  302. package/src/lib/resources/wso2carbon-publickey.cert +20 -0
  303. package/src/lib/rulesEngine.js +95 -0
  304. package/src/lib/rulesEngineModel.js +463 -0
  305. package/src/lib/scripting-engines/postman-sandbox.js +142 -0
  306. package/src/lib/scripting-engines/vm-javascript-sandbox.js +294 -0
  307. package/src/lib/server-logs/adapters/elastic-search.js +102 -0
  308. package/src/lib/server-logs/adapters/grafana.js +0 -0
  309. package/src/lib/server-logs/index.js +75 -0
  310. package/src/lib/socket-server.js +55 -0
  311. package/src/lib/storageAdapter.js +109 -0
  312. package/src/lib/test-outbound/TestCaseRunner.js +173 -0
  313. package/src/lib/test-outbound/getTracing.js +19 -0
  314. package/src/lib/test-outbound/outbound-initiator.js +1107 -0
  315. package/src/lib/uniqueIdGenerator.js +35 -0
  316. package/src/lib/utils.js +89 -0
  317. package/src/lib/utilsInternal.js +56 -0
  318. package/src/lib/webSocketClient/WebSocketClientManager.js +197 -0
  319. package/src/server.js +218 -0
@@ -0,0 +1,149 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Georgi Logodazhki <georgi.logodazhki@modusbox.com>
27
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
28
+ --------------
29
+ ******/
30
+
31
+ const express = require('express')
32
+ const router = new express.Router()
33
+ const jwt = require('jsonwebtoken')
34
+ const { verifyUser } = require('../api-server')
35
+ const Config = require('../config')
36
+ const LoginService = require('../oauth/LoginService')
37
+
38
+ router.post('/login', async (req, res, next) => {
39
+ try {
40
+ const response = await LoginService.loginUser(req.body.username, req.body.password, req, res)
41
+ res.status(200).json(response)
42
+ } catch (err) {
43
+ res.status(500).json({ error: err && err.message })
44
+ }
45
+ })
46
+
47
+ router.get('/logout', verifyUser(), async (req, res, next) => {
48
+ try {
49
+ await LoginService.logoutUser(req, res)
50
+ res.status(200).json({ message: 'logout successful' })
51
+ } catch (err) {
52
+ res.status(500).json({ error: err && err.message })
53
+ }
54
+ })
55
+
56
+ router.post('/token', async (req, res, next) => {
57
+ try {
58
+ const plainIdToken = {
59
+ username: req.body.username,
60
+ dfspId: req.body.username,
61
+ userguid: 'userguid'
62
+ }
63
+ let groupsData = [
64
+ 'Application/MTA',
65
+ 'Application/DFSP:' + req.body.username,
66
+ 'Internal/everyone'
67
+ ]
68
+ const systemConfig = Config.getSystemConfig()
69
+ if (req.body.username === systemConfig.CONNECTION_MANAGER.HUB_USERNAME) {
70
+ groupsData = [
71
+ 'Application/PTA',
72
+ 'Internal/everyone'
73
+ ]
74
+ } else if (systemConfig.HOSTING_ENABLED) {
75
+ // Check whether the DFSP exists in mock list
76
+ const dfspDB = require('../db/dfspMockUsers')
77
+ const dfspValid = await dfspDB.checkDFSP(req.body.username)
78
+ if (!dfspValid) {
79
+ throw (new Error('Invalid DFSP ID'))
80
+ }
81
+ }
82
+ const expiresIn = 3600
83
+ const iat = Date.now() / 1000
84
+ const plainAccessToken = {
85
+ exp: iat + expiresIn,
86
+ iat,
87
+ aud: systemConfig.OAUTH.APP_OAUTH_CLIENT_KEY,
88
+ sub: plainIdToken.username,
89
+ iss: systemConfig.OAUTH.OAUTH2_ISSUER,
90
+ groups: groupsData,
91
+ dfspId: plainIdToken.dfspId,
92
+ userguid: plainIdToken.userguid
93
+ }
94
+ res.status(200).json({
95
+ expires_in: expiresIn,
96
+ access_token: jwt.sign(plainAccessToken, systemConfig.OAUTH.EMBEDDED_CERTIFICATE),
97
+ id_token: jwt.sign(plainIdToken, systemConfig.OAUTH.EMBEDDED_CERTIFICATE)
98
+ })
99
+ } catch (err) {
100
+ res.status(500).json({ error: err && err.message })
101
+ }
102
+ })
103
+
104
+ // router.post('/token', async (req, res, next) => {
105
+ // try {
106
+ // let userDfspId = 'userdfsp'
107
+ // if (Config.getSystemConfig().HOSTING_ENABLED) {
108
+ // // Check whether the DFSP exists in mock list
109
+ // const dfspDB = require('../db/dfspMockUsers')
110
+ // const dfspValid = await dfspDB.checkDFSP(req.body.username)
111
+ // if (!dfspValid) {
112
+ // throw (new Error('Invalid DFSP ID'))
113
+ // }
114
+ // userDfspId = req.body.username
115
+ // }
116
+ // const idToken = jwt.sign(
117
+ // {
118
+ // at_hash: 'bJi28CeD9HLPf1ouOVkQTA',
119
+ // aud: 'CLIENT_KEY',
120
+ // sub: 'dfsp1',
121
+ // nbf: 1558709500,
122
+ // azp: 'CLIENT_KEY',
123
+ // amr: [
124
+ // 'password'
125
+ // ],
126
+ // iss: 'https://SERVERIP:9443/oauth2/token',
127
+ // groups: [
128
+ // 'Application/MTA',
129
+ // 'Application/DFSP:DFSP1',
130
+ // 'Internal/everyone'
131
+ // ],
132
+ // exp: 1558713100,
133
+ // iat: 1558709500,
134
+ // dfspId: userDfspId,
135
+ // userguid: 'userguid'
136
+ // }
137
+ // , 'password')
138
+ // res.status(200).json(
139
+ // {
140
+ // access_token: 'sometoken',
141
+ // id_token: idToken
142
+ // }
143
+ // )
144
+ // } catch (err) {
145
+ // res.status(500).json({ error: err && err.message })
146
+ // }
147
+ // })
148
+
149
+ module.exports = router
@@ -0,0 +1,53 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Georgi Logodazhki <georgi.logodazhki@modusbox.com> (Original Author)
27
+ --------------
28
+ ******/
29
+
30
+ const express = require('express')
31
+ const router = new express.Router()
32
+ const objectStore = require('../objectStore')
33
+
34
+ // Get runtime and stored user config
35
+ router.get('/:object', async (req, res, next) => {
36
+ try {
37
+ const object = objectStore.get(req.params.object, undefined, req.user)
38
+ res.status(200).json(object)
39
+ } catch (err) {
40
+ res.status(500).json({ error: err && err.message })
41
+ }
42
+ })
43
+
44
+ router.delete('/:object', async (req, res, next) => {
45
+ try {
46
+ objectStore.set(req.params.object, {}, req.user)
47
+ res.status(200).json({})
48
+ } catch (err) {
49
+ res.status(500).json({ error: err && err.message })
50
+ }
51
+ })
52
+
53
+ module.exports = router
@@ -0,0 +1,224 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
27
+ --------------
28
+ ******/
29
+
30
+ const express = require('express')
31
+ const router = new express.Router()
32
+ const utils = require('../utils')
33
+ const multer = require('multer')
34
+ const upload = multer({ dest: 'uploads/' })
35
+ const APIManagement = require('../api-management')
36
+
37
+ router.get('/api_versions', async (req, res, next) => {
38
+ try {
39
+ const apiDefinitions = await require('../mocking/openApiDefinitionsModel').getApiDefinitions()
40
+
41
+ if (apiDefinitions) {
42
+ res.status(200).json(apiDefinitions.map(item => {
43
+ return item
44
+ }))
45
+ } else {
46
+ res.status(404).json({ error: 'Can not read API versions' })
47
+ }
48
+ } catch (err) {
49
+ // next(err)
50
+ res.status(404).json({ error: err && err.message })
51
+ }
52
+ })
53
+
54
+ router.get('/definition/:type/:version', async (req, res, next) => {
55
+ try {
56
+ const openApiObjects = require('../mocking/openApiMockHandler').getOpenApiObjects()
57
+ const reqVersionArr = req.params.version.split('.')
58
+ const apiType = req.params.type
59
+
60
+ const reqOpenApiObject = openApiObjects.find((item) => {
61
+ if (item.majorVersion === +reqVersionArr[0] && item.minorVersion === +reqVersionArr[1] && item.type === apiType) {
62
+ return true
63
+ } else {
64
+ return false
65
+ }
66
+ })
67
+ if (reqOpenApiObject) {
68
+ res.status(200).json(reqOpenApiObject.openApiBackendObject.definition)
69
+ } else {
70
+ res.status(404).json({ error: 'Unknown Version' })
71
+ }
72
+ } catch (err) {
73
+ // next(err)
74
+ res.status(500).json({ error: err && err.message })
75
+ }
76
+ })
77
+
78
+ router.post('/definition', upload.single('file'), async (req, res, next) => {
79
+ const regex = /^([0-9]+)\.([0-9]+)$/
80
+ if (!regex.test(req.body.version)) {
81
+ return res.status(422).json({ errors: ['Version should be in the format x.x'] })
82
+ }
83
+ if (req.file) {
84
+ try {
85
+ await APIManagement.addDefinition(req.file.path, req.body.name, req.body.version, req.body.asynchronous)
86
+ // Remove temporary file
87
+ try { await utils.deleteFileAsync(req.file.path) } catch (err2) {}
88
+ res.status(200).json({ message: 'API has been added successfully', fileName: req.file })
89
+ } catch (err) {
90
+ try { await utils.deleteFileAsync(req.file.path) } catch (err2) {}
91
+ res.status(404).json({ error: 'Unknown format', message: err.message })
92
+ }
93
+ } else {
94
+ res.status(404).json({ error: 'File not found' })
95
+ }
96
+ })
97
+
98
+ router.delete('/definition/:type/:version', async (req, res, next) => {
99
+ const apiType = req.params.type
100
+ const apiVersion = req.params.version
101
+ try {
102
+ await APIManagement.deleteDefinition(apiType, apiVersion)
103
+ res.status(200).json({ message: 'API has been removed successfully' })
104
+ } catch (err) {
105
+ console.log(err)
106
+ res.status(404).json({ error: 'Unknown format', message: err.message })
107
+ }
108
+ })
109
+
110
+ router.put('/definition/:type/:version', async (req, res, next) => {
111
+ const apiType = req.params.type
112
+ const apiVersion = req.params.version
113
+ try {
114
+ await APIManagement.patchDefinitionParams(apiType, apiVersion, req.body)
115
+ res.status(200).json({ message: 'API parameters have been modified successfully' })
116
+ } catch (err) {
117
+ console.log(err)
118
+ res.status(404).json({ error: 'Unknown error', message: err.message })
119
+ }
120
+ })
121
+
122
+ router.post('/validate_definition', upload.single('file'), async (req, res, next) => {
123
+ if (req.file) {
124
+ try {
125
+ const document = await APIManagement.validateDefinition(req.file.path)
126
+ // Remove temporary file
127
+ try { await utils.deleteFileAsync(req.file.path) } catch (err2) {}
128
+ res.status(200).json({ apiDefinition: document, fileName: req.file })
129
+ } catch (err) {
130
+ try { await utils.deleteFileAsync(req.file.path) } catch (err2) {}
131
+ res.status(404).json({ error: 'Unknown format', message: err.message })
132
+ }
133
+ } else {
134
+ res.status(404).json({ error: 'File not found' })
135
+ }
136
+ })
137
+
138
+ router.get('/callback_map/:type/:version', async (req, res, next) => {
139
+ try {
140
+ const apiDefinitions = await require('../mocking/openApiDefinitionsModel').getApiDefinitions()
141
+ const reqVersionArr = req.params.version.split('.')
142
+ const apiType = req.params.type
143
+
144
+ const reqApiDefinition = apiDefinitions.find((item) => {
145
+ if (item.majorVersion === +reqVersionArr[0] && item.minorVersion === +reqVersionArr[1] && item.type === apiType) {
146
+ return true
147
+ } else {
148
+ return false
149
+ }
150
+ })
151
+ if (reqApiDefinition) {
152
+ try {
153
+ const rawdata = await utils.readFileAsync(reqApiDefinition.callbackMapFile)
154
+ const reqCallbackMap = JSON.parse(rawdata)
155
+
156
+ res.status(200).json(reqCallbackMap)
157
+ } catch (err) {
158
+ res.status(404).json({ error: 'Unknown Version' })
159
+ }
160
+ } else {
161
+ res.status(404).json({ error: 'Unknown Version' })
162
+ }
163
+ } catch (err) {
164
+ // next(err)
165
+ res.status(500).json({ error: err && err.message })
166
+ }
167
+ })
168
+
169
+ router.put('/callback_map/:type/:version', async (req, res, next) => {
170
+ try {
171
+ const apiDefinitions = await require('../mocking/openApiDefinitionsModel').getApiDefinitions()
172
+ const reqVersionArr = req.params.version.split('.')
173
+ const apiType = req.params.type
174
+
175
+ const reqApiDefinition = apiDefinitions.find((item) => {
176
+ if (item.majorVersion === +reqVersionArr[0] && item.minorVersion === +reqVersionArr[1] && item.type === apiType) {
177
+ return true
178
+ } else {
179
+ return false
180
+ }
181
+ })
182
+ if (reqApiDefinition) {
183
+ await utils.writeFileAsync(reqApiDefinition.callbackMapFile, JSON.stringify(req.body, null, 2))
184
+ res.status(200).json({})
185
+ } else {
186
+ res.status(404).json({ error: 'Unknown Version' })
187
+ }
188
+ } catch (err) {
189
+ // next(err)
190
+ res.status(500).json({ error: err && err.message })
191
+ }
192
+ })
193
+
194
+ router.get('/response_map/:type/:version', async (req, res, next) => {
195
+ try {
196
+ const apiDefinitions = await require('../mocking/openApiDefinitionsModel').getApiDefinitions()
197
+ const reqVersionArr = req.params.version.split('.')
198
+ const apiType = req.params.type
199
+
200
+ const reqApiDefinition = apiDefinitions.find((item) => {
201
+ if (item.majorVersion === +reqVersionArr[0] && item.minorVersion === +reqVersionArr[1] && item.type === apiType) {
202
+ return true
203
+ } else {
204
+ return false
205
+ }
206
+ })
207
+ if (reqApiDefinition) {
208
+ try {
209
+ const rawdata = await utils.readFileAsync(reqApiDefinition.responseMapFile)
210
+ const reqResponseMap = JSON.parse(rawdata)
211
+ res.status(200).json(reqResponseMap)
212
+ } catch (err) {
213
+ res.status(404).json({ error: 'Unknown Version' })
214
+ }
215
+ } else {
216
+ res.status(404).json({ error: 'Unknown Version' })
217
+ }
218
+ } catch (err) {
219
+ // next(err)
220
+ res.status(500).json({ error: err && err.message })
221
+ }
222
+ })
223
+
224
+ module.exports = router
@@ -0,0 +1,134 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Georgi Logodazhki <georgi.logodazhki@modusbox.com>
27
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
28
+ --------------
29
+ ******/
30
+
31
+ const express = require('express')
32
+
33
+ const router = new express.Router()
34
+ const axios = require('axios').default
35
+ const Config = require('../config')
36
+ const customLogger = require('../requestLogger')
37
+ const outbound = require('../test-outbound/outbound-initiator')
38
+ const { check, validationResult } = require('express-validator')
39
+
40
+ // Route to send a single outbound request
41
+ router.post('/request', [
42
+ check('method').notEmpty(),
43
+ check('path').notEmpty()
44
+ ],
45
+ async (req, res, next) => {
46
+ const errors = validationResult(req)
47
+ if (!errors.isEmpty()) {
48
+ return res.status(422).json({ errors: errors.array() })
49
+ }
50
+ try {
51
+ axios({
52
+ method: req.body.method,
53
+ url: req.body.url ? req.body.url : (await Config.getUserConfig(req.user)).CALLBACK_ENDPOINT + req.body.path,
54
+ headers: req.body.headers,
55
+ data: req.body.body,
56
+ timeout: 3000,
57
+ validateStatus: (status) => {
58
+ return status < 900 // Reject only if the status code is greater than or equal to 900
59
+ }
60
+ }).then((result) => {
61
+ customLogger.logMessage('info', 'Received response ' + result.status + ' ' + result.statusText, { additionalData: result.data, notification: false, user: req.user })
62
+ }, (err) => {
63
+ customLogger.logMessage('info', 'Failed to send request ' + req.body.method + ' ' + req.body.path, { additionalData: err, notification: false, user: req.user })
64
+ })
65
+ res.status(200).json({ status: 'OK' })
66
+ } catch (err) {
67
+ res.status(500).json({ error: err && err.message })
68
+ }
69
+ })
70
+
71
+ // Route to send series of outbound requests based on the given template
72
+ router.post('/template/:traceID', [
73
+ check('name').notEmpty(),
74
+ check('test_cases').notEmpty()
75
+ ], async (req, res, next) => {
76
+ try {
77
+ const errors = validationResult(req)
78
+ if (!errors.isEmpty()) {
79
+ return res.status(422).json({ errors: errors.array() })
80
+ }
81
+ const traceID = req.params.traceID
82
+ const inputJson = JSON.parse(JSON.stringify(req.body))
83
+ // TODO: Change the following value to the dfspId based on the login incase HOSTING_ENABLED
84
+ const dfspId = req.user ? req.user.dfspId : null
85
+ if (req.query?.sync === 'true') {
86
+ const result = await outbound.OutboundSend(inputJson, traceID, dfspId, true, req.metrics)
87
+ return res.status(200).json(result)
88
+ } else {
89
+ outbound.OutboundSend(inputJson, traceID, dfspId, false, req.metrics)
90
+ return res.status(200).json({ status: 'OK' })
91
+ }
92
+ } catch (err) {
93
+ res.status(500).json({ error: err && err.message })
94
+ }
95
+ })
96
+
97
+ router.post('/template_iterations/:traceID', [
98
+ check('name').notEmpty(),
99
+ check('iterationCount').notEmpty(),
100
+ check('test_cases').notEmpty()
101
+ ], async (req, res, next) => {
102
+ try {
103
+ const errors = validationResult(req)
104
+ if (!errors.isEmpty()) {
105
+ return res.status(422).json({ errors: errors.array() })
106
+ }
107
+ if (+req.query.iterationCount === 0) {
108
+ throw new Error('Iteration count is zero')
109
+ }
110
+ const traceID = req.params.traceID
111
+ const inputJson = JSON.parse(JSON.stringify(req.body))
112
+ // TODO: Change the following value to the dfspId based on the login incase HOSTING_ENABLED
113
+ const dfspId = req.user ? req.user.dfspId : null
114
+ outbound.OutboundSendLoop(inputJson, traceID, dfspId, req.query.iterationCount)
115
+
116
+ return res.status(200).json({ status: 'OK' })
117
+ } catch (err) {
118
+ res.status(500).json({ error: err && err.message })
119
+ }
120
+ })
121
+
122
+ // Route to terminate the given execution
123
+ router.delete('/template/:traceID', async (req, res, next) => {
124
+ try {
125
+ const traceID = req.params.traceID
126
+ outbound.terminateOutbound(traceID)
127
+
128
+ return res.status(200).json({ status: 'OK' })
129
+ } catch (err) {
130
+ res.status(500).json({ error: err && err.message })
131
+ }
132
+ })
133
+
134
+ module.exports = router
@@ -0,0 +1,72 @@
1
+ /*****
2
+ License
3
+ --------------
4
+ Copyright © 2020-2025 Mojaloop Foundation
5
+ The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ Contributors
12
+ --------------
13
+ This is the official list of the Mojaloop project contributors for this file.
14
+ Names of the original copyright holders (individuals or organizations)
15
+ should be listed with a '*' in the first column. People who have
16
+ contributed from an organization can be listed under the organization
17
+ that actually holds the copyright for their contributions (see the
18
+ Mojaloop Foundation for an example). Those individuals should have
19
+ their names indented and be marked with a '-'. Email address can be added
20
+ optionally within square brackets <email>.
21
+
22
+ * Mojaloop Foundation
23
+ - Name Surname <name.surname@mojaloop.io>
24
+
25
+ * ModusBox
26
+ * Vijaya Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
27
+ --------------
28
+ ******/
29
+
30
+ const express = require('express')
31
+ const router = new express.Router()
32
+ // const { check, validationResult } = require('express-validator')
33
+ const reportGenerator = require('../report-generator/generator')
34
+
35
+ // Generate report
36
+ router.post('/testcase/:format', async (req, res, next) => {
37
+ const jsonReport = req.body
38
+ const format = req.params.format
39
+ let downloadFileSuffix = '.html'
40
+
41
+ if (jsonReport.runtimeInformation) {
42
+ downloadFileSuffix = '-' + jsonReport.runtimeInformation.completedTimeISO + downloadFileSuffix
43
+ }
44
+ downloadFileSuffix = '-' + jsonReport.name + downloadFileSuffix
45
+ try {
46
+ const result = await reportGenerator.generateReport(jsonReport, format)
47
+ res.setHeader('Content-disposition', 'attachment; filename=TTK-Assertion-Report' + downloadFileSuffix)
48
+ res.setHeader('TTK-FileName', 'TTK-Assertion-Report' + downloadFileSuffix)
49
+ res.status(200).send(result)
50
+ } catch (err) {
51
+ res.status(500).json({ error: err && err.message })
52
+ }
53
+ })
54
+
55
+ // Generate report
56
+ router.post('/testcase_definition/:format', async (req, res, next) => {
57
+ const template = req.body
58
+ const format = req.params.format
59
+ let downloadFileSuffix = '.html'
60
+
61
+ downloadFileSuffix = '-' + template.name + downloadFileSuffix
62
+ try {
63
+ const result = await reportGenerator.generateTestcaseDefinition(template, format)
64
+ res.setHeader('Content-disposition', 'attachment; filename=TTK-Testcase-Definition' + downloadFileSuffix)
65
+ res.setHeader('TTK-FileName', 'TTK-Testcase-Definition' + downloadFileSuffix)
66
+ res.status(200).send(result)
67
+ } catch (err) {
68
+ res.status(500).json({ error: err && err.message })
69
+ }
70
+ })
71
+
72
+ module.exports = router