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,181 @@
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 Cookies = require('cookies')
31
+ const passport = require('passport')
32
+ const Config = require('../config')
33
+ const fs = require('fs')
34
+ const path = require('path')
35
+ const customLogger = require('../requestLogger')
36
+
37
+ function cookieExtractor (req) {
38
+ const cookies = new Cookies(req)
39
+ const token = cookies.get('TTK-API_ACCESS_TOKEN')
40
+ return token
41
+ }
42
+
43
+ /**
44
+ * Creates a JWTStrategy to use with passport
45
+ * @see http://www.passportjs.org/packages/passport-jwt/
46
+ */
47
+ function createJwtStrategy (extraExtractors) {
48
+ const systemConfig = Config.getSystemConfig()
49
+ const JwtStrategy = require('passport-jwt').Strategy
50
+ const ExtractJwt = require('passport-jwt').ExtractJwt
51
+
52
+ const jwtStrategyOpts = {}
53
+ let extractors = []
54
+ if (extraExtractors) {
55
+ if (Array.isArray(extraExtractors)) {
56
+ extractors = extractors.concat(extraExtractors)
57
+ } else {
58
+ extractors.push(extraExtractors)
59
+ }
60
+ }
61
+ extractors = extractors.concat([ExtractJwt.fromAuthHeaderAsBearerToken(), cookieExtractor])
62
+
63
+ jwtStrategyOpts.jwtFromRequest = ExtractJwt.fromExtractors(extractors)
64
+
65
+ jwtStrategyOpts.passReqToCallback = true // passReqToCallback: If true the request will be passed to the verify callback. i.e. verify(request, jwt_payload, done_callback).
66
+ jwtStrategyOpts.jsonWebTokenOptions = {}
67
+ let certContent
68
+ if (systemConfig.OAUTH.EMBEDDED_CERTIFICATE) {
69
+ customLogger.logMessage('info', 'Setting Token Issuer certificate from Constants.OAUTH.EMBEDDED_CERTIFICATE', { notification: false })
70
+ certContent = systemConfig.OAUTH.EMBEDDED_CERTIFICATE
71
+ } else if (systemConfig.OAUTH.CERTIFICATE_FILE_NAME) {
72
+ customLogger.logMessage('info', `Setting Token Issuer certificate from Constants.OAUTH.CERTIFICATE_FILE_NAME: ${systemConfig.OAUTH.CERTIFICATE_FILE_NAME}`, { notification: false })
73
+ if (systemConfig.OAUTH.CERTIFICATE_FILE_NAME.startsWith('/')) {
74
+ customLogger.logMessage('info', 'Token Issuer Constants.OAUTH.CERTIFICATE_FILE_NAME absolute path', { notification: false })
75
+ certContent = fs.readFileSync(systemConfig.OAUTH.CERTIFICATE_FILE_NAME, 'utf8')
76
+ } else {
77
+ customLogger.logMessage('info', 'Token Issuer Constants.OAUTH.CERTIFICATE_FILE_NAME relative path', { notification: false })
78
+ certContent = fs.readFileSync(path.join(__dirname, '..', systemConfig.OAUTH.CERTIFICATE_FILE_NAME), 'utf8')
79
+ }
80
+ } else {
81
+ customLogger.logMessage('warn', 'No value specified for Constants.OAUTH.CERTIFICATE_FILE_NAME or Constants.OAUTH.EMBEDDED_CERTIFICATE. Auth will probably fail to validate the tokens', { notification: false })
82
+ }
83
+ customLogger.logMessage('info', `Token Issuer loaded: ${certContent}`, { notification: false })
84
+
85
+ jwtStrategyOpts.secretOrKey = certContent
86
+ // jwtStrategyOpts.secretOrKeyProvider = (request, rawJwtToken, done) => {
87
+ // done(null, certContent)
88
+ // }
89
+ // jwtStrategyOpts.issuer = 'accounts.examplesoft.com'
90
+ // jwtStrategyOpts.audience = systemConfig.OAUTH.APP_OAUTH_CLIENT_KEY // audience: If defined, the token audience (aud) will be verified against this value.
91
+ const jwtStrategy = new JwtStrategy(jwtStrategyOpts, verifyCallback)
92
+ return jwtStrategy
93
+ }
94
+
95
+ /**
96
+ * Verifies the basic jwtPayload parameters, whatever it is needed before checking for the specific permissions
97
+ * requested by the req
98
+ *
99
+ * This validates the issuer, sub, that the jwt has groups, and the creates a client and authInfo and calls the callback
100
+ *
101
+ * @param {Request} req http request
102
+ * @param {Object} jwtPayload JWT Payload as an Object
103
+ * @param {function(err, client|false, authInfo)} done callback called with the verification results
104
+ */
105
+ function verifyCallback (req, jwtPayload, done) {
106
+ if (!jwtPayload.sub) {
107
+ const message = 'Invalid Authentication info: no sub'
108
+ customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
109
+ return done(null, false, message)
110
+ }
111
+ if (!jwtPayload.iss) {
112
+ const message = 'Invalid Authentication info: no iss'
113
+ customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
114
+ return done(null, false, message)
115
+ }
116
+ const systemConfig = Config.getSystemConfig()
117
+ if (jwtPayload.iss !== systemConfig.OAUTH.OAUTH2_ISSUER && jwtPayload.iss !== systemConfig.OAUTH.OAUTH2_TOKEN_ISS) {
118
+ const message = `Invalid Authentication: wrong issuer ${jwtPayload.iss}, expecting: ${systemConfig.OAUTH.OAUTH2_ISSUER} or ${systemConfig.OAUTH.OAUTH2_TOKEN_ISS}`
119
+ customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
120
+ return done(null, false, message)
121
+ }
122
+ if (!jwtPayload.groups) {
123
+ const message = 'Invalid Authentication info: no groups'
124
+ customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
125
+ return done(null, false, message)
126
+ }
127
+ const foundMTA = jwtPayload.groups.includes(systemConfig.OAUTH.MTA_ROLE)
128
+ const foundPTA = jwtPayload.groups.includes(systemConfig.OAUTH.PTA_ROLE)
129
+ const foundEveryone = jwtPayload.groups.includes(systemConfig.OAUTH.EVERYONE_ROLE)
130
+ const client = { name: jwtPayload.sub, dfspId: jwtPayload.dfspId }
131
+ const roles = { mta: foundMTA, pta: foundPTA, everyone: foundEveryone }
132
+ for (const group of jwtPayload.groups) {
133
+ roles[group] = true
134
+ }
135
+ const authInfo = { roles }
136
+ return done(null, client, authInfo)
137
+ }
138
+
139
+ /**
140
+ * Creates a passport OAUth2 authenticating middleware
141
+ *
142
+ * @returns a connect middleware that handles OAuth2
143
+ */
144
+ function getOAuth2Middleware () {
145
+ const jwtStrategy = createJwtStrategy()
146
+ passport.use(jwtStrategy)
147
+ }
148
+
149
+ const handleMiddleware = () => {
150
+ if (Config.getSystemConfig().OAUTH && Config.getSystemConfig().OAUTH.AUTH_ENABLED) {
151
+ customLogger.logMessage('info', 'Enabling OAUTH', { notification: false })
152
+ getOAuth2Middleware()
153
+ } else {
154
+ customLogger.logMessage('info', 'NOT enabling OAUTH', { notification: false })
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Validates that the user has the required permissions to execute the operation.
160
+ *
161
+ * callback accepts one
162
+ * argument - an Error if unauthorized. The Error may include "message",
163
+ * "state", and "code" fields to be conveyed to the client in the response
164
+ * body and a "headers" field containing an object representing headers
165
+ * to be set on the response to the client. In addition, if the Error has
166
+ * a statusCode field, the response statusCode will be set to match -
167
+ * otherwise, the statusCode will be set to 403.
168
+ *
169
+ * @param {Request} req HTTP request. req.user and req.authInfo come from the passport verify callback (`return done(null, client, authInfo)`)
170
+ * @param {SecurityDefiniton} securityDefinition SecurityDefiniton from the swagger doc
171
+ * @param {String} scopes scopes required for this operation from the operation definition in the Swagger doc. Same as req.swagger.security[0].OAuth2
172
+ * @param {(error)} callback function to call with the result. If unauthorized, send the error.
173
+ */
174
+
175
+ module.exports = {
176
+ getOAuth2Middleware,
177
+ handleMiddleware,
178
+ cookieExtractor,
179
+ createJwtStrategy,
180
+ verifyCallback
181
+ }
@@ -0,0 +1,118 @@
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
+ * Vijay Kumar Guthi <vijaya.guthi@modusbox.com> (Original Author)
27
+ --------------
28
+ ******/
29
+
30
+ const Config = require('../config')
31
+ const Utils = require('../utils')
32
+ const path = require('path')
33
+ const customLogger = require('../requestLogger')
34
+ const { promisify } = require('util')
35
+ const jwt = require('jsonwebtoken')
36
+ const readFileAsync = Utils.readFileAsync
37
+
38
+ const verifyToken = async (token) => {
39
+ const systemConfig = Config.getSystemConfig()
40
+
41
+ let certContent
42
+ if (systemConfig.OAUTH.EMBEDDED_CERTIFICATE) {
43
+ customLogger.logMessage('info', 'Setting Token Issuer certificate from Constants.OAUTH.EMBEDDED_CERTIFICATE', { notification: false })
44
+ certContent = systemConfig.OAUTH.EMBEDDED_CERTIFICATE
45
+ } else if (systemConfig.OAUTH.CERTIFICATE_FILE_NAME) {
46
+ customLogger.logMessage('info', `Setting Token Issuer certificate from Constants.OAUTH.CERTIFICATE_FILE_NAME: ${systemConfig.OAUTH.CERTIFICATE_FILE_NAME}`, { notification: false })
47
+ if (systemConfig.OAUTH.CERTIFICATE_FILE_NAME.startsWith('/')) {
48
+ customLogger.logMessage('info', 'Token Issuer Constants.OAUTH.CERTIFICATE_FILE_NAME absolute path', { notification: false })
49
+ certContent = await readFileAsync(systemConfig.OAUTH.CERTIFICATE_FILE_NAME, 'utf8')
50
+ } else {
51
+ customLogger.logMessage('info', 'Token Issuer Constants.OAUTH.CERTIFICATE_FILE_NAME relative path', { notification: false })
52
+ certContent = await readFileAsync(path.join(__dirname, '..', systemConfig.OAUTH.CERTIFICATE_FILE_NAME), 'utf8')
53
+ }
54
+ } else {
55
+ customLogger.logMessage('warn', 'No value specified for Constants.OAUTH.CERTIFICATE_FILE_NAME or Constants.OAUTH.EMBEDDED_CERTIFICATE. Auth will probably fail to validate the tokens', { notification: false })
56
+ }
57
+ customLogger.logMessage('info', `Token Issuer loaded: ${certContent}`, { notification: false })
58
+ const jwtOpts = {}
59
+ // jwtOpts.audience = systemConfig.OAUTH.APP_OAUTH_CLIENT_KEY // audience: If defined, the token audience (aud) will be verified against this value.
60
+ // const jwtStrategy = new JwtStrategy(jwtOpts, verifyCallback)
61
+ const jwtPayload = await promisify(jwt.verify)(token, certContent, jwtOpts)
62
+ additionalVerification(jwtPayload)
63
+ const dfspId = getDfspIdFromClientToken(jwtPayload)
64
+ return {
65
+ dfspId,
66
+ decodedToken: jwtPayload
67
+ }
68
+ }
69
+
70
+ // function getDfspIdFromUserToken (jwtPayload) {
71
+ // let dfspId = null
72
+ // if (jwtPayload.dfspId) {
73
+ // dfspId = jwtPayload.dfspId
74
+ // } else {
75
+ // const dfspGroup = jwtPayload.groups.find(groupName => groupName.startsWith('Application/DFSP:'))
76
+ // if (dfspGroup) {
77
+ // dfspId = dfspGroup.replace('Application/DFSP:', '')
78
+ // }
79
+ // }
80
+ // return dfspId
81
+ // }
82
+
83
+ function getDfspIdFromClientToken (jwtPayload) {
84
+ return jwtPayload.clientId
85
+ }
86
+
87
+ function additionalVerification (jwtPayload) {
88
+ if (!jwtPayload.sub) {
89
+ const message = 'Invalid Authentication info: no sub'
90
+ customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
91
+ throw (new Error(message))
92
+ }
93
+ if (!jwtPayload.iss) {
94
+ const message = 'Invalid Authentication info: no iss'
95
+ customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
96
+ throw (new Error(message))
97
+ }
98
+ // const systemConfig = Config.getSystemConfig()
99
+ // if (jwtPayload.iss !== systemConfig.OAUTH.OAUTH2_ISSUER && jwtPayload.iss !== systemConfig.OAUTH.OAUTH2_TOKEN_ISS) {
100
+ // const message = `Invalid Authentication: wrong issuer ${jwtPayload.iss}, expecting: ${systemConfig.OAUTH.OAUTH2_ISSUER} or ${systemConfig.OAUTH.OAUTH2_TOKEN_ISS}`
101
+ // customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
102
+ // throw (new Error(message))
103
+ // }
104
+ // if (!jwtPayload.groups) {
105
+ // const message = 'Invalid Authentication info: no groups'
106
+ // customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
107
+ // throw (new Error(message))
108
+ // }
109
+ if (!jwtPayload.clientId) {
110
+ const message = 'There is no clientId specified'
111
+ customLogger.logMessage('error', `OAuthHelper.verifyCallback received ${jwtPayload}. Verification failed because ${message}`, { notification: false })
112
+ throw (new Error(message))
113
+ }
114
+ }
115
+
116
+ module.exports = {
117
+ verifyToken
118
+ }
@@ -0,0 +1,64 @@
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
+ 'use strict'
31
+ const Config = require('../config')
32
+ const axios = require('axios')
33
+ const customLogger = require('../requestLogger')
34
+
35
+ exports.getToken = async (username, password) => {
36
+ const form = new URLSearchParams({
37
+ username,
38
+ password,
39
+ scope: 'openid',
40
+ grant_type: 'password'
41
+ })
42
+
43
+ try {
44
+ const Constants = Config.getSystemConfig()
45
+ const url = Constants.OAUTH.OAUTH2_ISSUER
46
+ const response = await axios.post(url, form.toString(), {
47
+ headers: {
48
+ 'Content-Type': 'application/x-www-form-urlencoded'
49
+ },
50
+ auth: {
51
+ username: Constants.OAUTH.APP_OAUTH_CLIENT_KEY,
52
+ password: Constants.OAUTH.APP_OAUTH_CLIENT_SECRET
53
+ }
54
+ })
55
+
56
+ customLogger.logMessage('info', `Wso2Client.getToken received ${JSON.stringify(response.data)}`, { notification: false })
57
+ return response.data
58
+ } catch (error) {
59
+ if (error.response?.status === 400 && error.response?.data?.message.includes('Authentication failed')) {
60
+ throw new Error(`Authentication failed for user ${username}`)
61
+ }
62
+ throw error
63
+ }
64
+ }
@@ -0,0 +1,50 @@
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 storedObject = {
31
+ transactions: {}
32
+ }
33
+
34
+ const set = async (key, value) => {
35
+ storedObject[key] = { ...value }
36
+ }
37
+
38
+ const get = async (key) => {
39
+ return { ...storedObject[key] }
40
+ }
41
+
42
+ const init = async () => {
43
+ return null
44
+ }
45
+
46
+ module.exports = {
47
+ set,
48
+ get,
49
+ init
50
+ }
@@ -0,0 +1,51 @@
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 objectStoreImpl = require('./inMemoryImpl')
31
+
32
+ const set = async (key, value) => {
33
+ // console.log('### OBJECT_STORE #### Setting key', key, 'Value', value )
34
+ await objectStoreImpl.set(key, value)
35
+ }
36
+
37
+ const get = async (key) => {
38
+ const value = await objectStoreImpl.get(key)
39
+ // console.log('### OBJECT_STORE #### Getting key', key, 'Value', value )
40
+ return value
41
+ }
42
+
43
+ const init = async () => {
44
+ await objectStoreImpl.init()
45
+ }
46
+
47
+ module.exports = {
48
+ set,
49
+ get,
50
+ init
51
+ }
@@ -0,0 +1,122 @@
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 _ = require('lodash')
32
+
33
+ const storedObject = {
34
+ data: {
35
+ transactions: {},
36
+ inboundEnvironment: {},
37
+ requests: {},
38
+ callbacks: {}
39
+ }
40
+ }
41
+
42
+ const init = (key, user) => {
43
+ const context = user ? user.dfspId : 'data'
44
+ if (!storedObject[context]) {
45
+ storedObject[context] = {}
46
+ }
47
+ if (!storedObject[context][key]) {
48
+ storedObject[context][key] = {}
49
+ }
50
+ return context
51
+ }
52
+
53
+ const set = (key, value, user) => {
54
+ const context = init(key, user)
55
+ storedObject[context][key] = { ...value }
56
+ }
57
+
58
+ const get = (key, item, user) => {
59
+ const context = init(key, user)
60
+ if (item) {
61
+ if (storedObject[context][key][item]) {
62
+ return { ...storedObject[context][key][item] }
63
+ }
64
+ return null
65
+ } else {
66
+ return { ...storedObject[context][key] }
67
+ }
68
+ }
69
+
70
+ const push = (key, item, value, user) => {
71
+ const context = init(key, user)
72
+ storedObject[context][key][item] = {
73
+ insertedDate: Date.now(),
74
+ data: JSON.parse(JSON.stringify(value))
75
+ }
76
+ }
77
+
78
+ const clear = (object, interval) => {
79
+ for (const context in storedObject) {
80
+ for (const item in storedObject[context][object]) {
81
+ const timeDiff = Date.now() - storedObject[context][object][item].insertedDate
82
+ if (timeDiff > interval) {
83
+ delete storedObject[context][object][item]
84
+ }
85
+ }
86
+ }
87
+ }
88
+
89
+ const popObject = (key, item, user) => {
90
+ const context = init(key, user)
91
+ if (Object.prototype.hasOwnProperty.call(storedObject[context][key], item)) {
92
+ const foundData = JSON.parse(JSON.stringify(storedObject[context][key][item].data))
93
+ delete storedObject[context][key][item]
94
+ return foundData
95
+ }
96
+ return null
97
+ }
98
+
99
+ const clearOldObjects = () => {
100
+ const interval = 10 * 60 * 1000
101
+ clear('transactions', interval)
102
+ clear('requests', interval)
103
+ clear('callbacks', interval)
104
+ clear('requestsHistory', interval)
105
+ clear('callbacksHistory', interval)
106
+ }
107
+
108
+ const initObjectStore = (initConfig = null) => {
109
+ if (initConfig) {
110
+ _.merge(storedObject.data, initConfig)
111
+ }
112
+ setInterval(clearOldObjects, 1000)
113
+ }
114
+
115
+ module.exports = {
116
+ set,
117
+ get,
118
+ initObjectStore,
119
+ push,
120
+ clear,
121
+ popObject
122
+ }