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.
- package/.dockerignore +10 -0
- package/.grype.yaml +16 -0
- package/.ncurc.yaml +9 -0
- package/.nvmrc +1 -0
- package/.versionrc.js +16 -0
- package/CHANGELOG.md +504 -0
- package/CODEOWNERS +30 -0
- package/Dockerfile +42 -0
- package/Dockerfile-newman +13 -0
- package/LICENSE.md +9 -0
- package/README.md +119 -0
- package/assets/diagrams/architectural/architectural-diagram.svg +3 -0
- package/assets/diagrams/flow/flow-diagram.svg +3 -0
- package/assets/images/Sample-Response-Failure.png +0 -0
- package/assets/images/Screenshot 2020-04-16 at 22.58.04.png +0 -0
- package/assets/images/TLS-Enabled-on-Environment.png +0 -0
- package/assets/images/adapter-mutual-tls-enabled.png +0 -0
- package/assets/images/add-additional-input-values.png +0 -0
- package/assets/images/add-condition-button.png +0 -0
- package/assets/images/add-new-assertion.png +0 -0
- package/assets/images/add-new-input-value.png +0 -0
- package/assets/images/add-new-input-variable.png +0 -0
- package/assets/images/additional-transfers.png +0 -0
- package/assets/images/api-provisioning-add-new-api-confirmation.png +0 -0
- package/assets/images/api-provisioning-file-input-window.png +0 -0
- package/assets/images/api-provisioning-list-apis-view.png +0 -0
- package/assets/images/api-provisioning-menu-item.png +0 -0
- package/assets/images/apply_and_restart.jpg +0 -0
- package/assets/images/assess-request-or-response.png +0 -0
- package/assets/images/assess-response-equation-save.png +0 -0
- package/assets/images/assess-response-equation.png +0 -0
- package/assets/images/assess-response-status.png +0 -0
- package/assets/images/building-new-rules-file.png +0 -0
- package/assets/images/callback-rules-screen.png +0 -0
- package/assets/images/configurable-parameter-assertion.png +0 -0
- package/assets/images/configurable-parameter-currency.png +0 -0
- package/assets/images/configurable-parameter.png +0 -0
- package/assets/images/connection-manager-ui-opening.png +0 -0
- package/assets/images/create-inbound-user-simulator.png +0 -0
- package/assets/images/creating-new-rule-file.png +0 -0
- package/assets/images/dfsp-client-cacert.png +0 -0
- package/assets/images/dfsp-client-submit.png +0 -0
- package/assets/images/dfsp-client.png +0 -0
- package/assets/images/dfsp-p2p-happy-path.png +0 -0
- package/assets/images/dfsp-server-cacert.png +0 -0
- package/assets/images/dfsp-server-cert.png +0 -0
- package/assets/images/download-report.png +0 -0
- package/assets/images/drive_have_not_been_shared.jpg +0 -0
- package/assets/images/event-response-options.png +0 -0
- package/assets/images/expand-monitoring-messages.png +0 -0
- package/assets/images/fixed-response-sample.png +0 -0
- package/assets/images/header-selection.png +0 -0
- package/assets/images/heap_error_windows.jpg +0 -0
- package/assets/images/hosted-mode-docker-compose-intro.png +0 -0
- package/assets/images/hub-client-cert.png +0 -0
- package/assets/images/import-template.png +0 -0
- package/assets/images/inbound-requests-environment.png +0 -0
- package/assets/images/inbound-requests-scripts.png +0 -0
- package/assets/images/jws-certificate-submit.png +0 -0
- package/assets/images/jws-certificate.png +0 -0
- package/assets/images/jws-certs-keys.png +0 -0
- package/assets/images/jws-hub-certs-keys.png +0 -0
- package/assets/images/local-enable-jws-publickey.png +0 -0
- package/assets/images/local-mutual-tls-enabled.png +0 -0
- package/assets/images/local_drives_to_be_available.jpg +0 -0
- package/assets/images/mcm-environment-opening.png +0 -0
- package/assets/images/menu-items.png +0 -0
- package/assets/images/mock-response-sample.png +0 -0
- package/assets/images/monitoring-initial-state.png +0 -0
- package/assets/images/monitoring-messages.png +0 -0
- package/assets/images/new-empty-assertion.png +0 -0
- package/assets/images/opened-imported-template.png +0 -0
- package/assets/images/opening-default-settings.png +0 -0
- package/assets/images/opening-sync-response-rules.png +0 -0
- package/assets/images/opening-view.png +0 -0
- package/assets/images/outbound-display-opening-hub.png +0 -0
- package/assets/images/outbound-display-opening.png +0 -0
- package/assets/images/override-with-environment-variable.png +0 -0
- package/assets/images/populate-with-sample-body.png +0 -0
- package/assets/images/resource-selection.png +0 -0
- package/assets/images/rule-builder-select-api.png +0 -0
- package/assets/images/sample-condition-add-configurable-params.png +0 -0
- package/assets/images/sample-condition.png +0 -0
- package/assets/images/sample-editor.png +0 -0
- package/assets/images/sample-request.png +0 -0
- package/assets/images/sample-test-assertion.png +0 -0
- package/assets/images/send-transfer.png +0 -0
- package/assets/images/sending-single-test-case-1.png +0 -0
- package/assets/images/sending-single-test-case-2.png +0 -0
- package/assets/images/sending-test-cases.png +0 -0
- package/assets/images/server-certificates-submitted.png +0 -0
- package/assets/images/simulator-response.png +0 -0
- package/assets/images/simulator-scheme-adapter-endpoint.png +0 -0
- package/assets/images/summarized-view-of-rule.png +0 -0
- package/assets/images/template-window.png +0 -0
- package/assets/images/test-case-editor-console-log.png +0 -0
- package/assets/images/test-case-editor-environment-state.png +0 -0
- package/assets/images/test-case-editor-scripts.png +0 -0
- package/assets/images/test-case-editor.png +0 -0
- package/assets/images/testcase-definition-download.png +0 -0
- package/assets/images/testcase-definition-edit-meta-info.png +0 -0
- package/assets/images/testing-toolkit-mojaloop-testing-toolkit-endpoint.png +0 -0
- package/assets/images/tls-hub-certs-keys.png +0 -0
- package/assets/images/tls-jws-enabled-on-environment.png +0 -0
- package/assets/images/updated-sample-body-data.png +0 -0
- package/assets/images/using-configurable-parameter.png +0 -0
- package/assets/images/validation-rules-screen.png +0 -0
- package/assets/images/view-response.png +0 -0
- package/audit-ci.jsonc +7 -0
- package/connection-manager/docker-compose.yml +55 -0
- package/database/docker-compose.yml +16 -0
- package/docker/hosted-mode/docker-compose.yaml +107 -0
- package/docker/hosted-mode/keycloak/keycloak-realm.json +2298 -0
- package/docker/hosted-mode/mongo-init.sh +1 -0
- package/docker/hosted-mode-tls/docker-compose.yaml +171 -0
- package/docker/hosted-mode-tls/keycloak/keycloak-realm.json +2298 -0
- package/docker/hosted-mode-tls/mongo-init.sh +1 -0
- package/docker-compose.yml +62 -0
- package/documents/Mojaloop-Testing-Toolkit.md +296 -0
- package/documents/RULES_ENGINE.md +403 -0
- package/documents/User-Guide-API-Provisioning.md +121 -0
- package/documents/User-Guide-CLI.md +218 -0
- package/documents/User-Guide-Connection-Manager.md +282 -0
- package/documents/User-Guide-Frequently-Asked-Questions.md +39 -0
- package/documents/User-Guide-Hosted-Mode-Docker-Compose.md +110 -0
- package/documents/User-Guide-Installation.md +163 -0
- package/documents/User-Guide-Mojaloop-Testing-Toolkit.md +642 -0
- package/documents/User-Guide-OAuth-Server-Deployment.md +283 -0
- package/documents/User-Guide-Onboarding-DFSP.md +197 -0
- package/documents/User-Guide-Onboarding-HUB.md +191 -0
- package/documents/User-Guide.md +53 -0
- package/examples/collections/dfsp/p2p_failed_tests.json +7161 -0
- package/examples/collections/dfsp/p2p_fx_happy_path.json +502 -0
- package/examples/collections/dfsp/p2p_happy_path.json +350 -0
- package/examples/collections/dfsp/p2p_happy_path_extended.json +6106 -0
- package/examples/collections/dfsp/p2p_happy_path_jws.json +511 -0
- package/examples/collections/dfsp/p2p_payee_assertions_websocket.json +441 -0
- package/examples/collections/dfsp/sample.json +5029 -0
- package/examples/collections/dfsp/transaction_request_service.json +240 -0
- package/examples/collections/fxp/FXP.json +264 -0
- package/examples/collections/fxp/SDK_backend.json +98 -0
- package/examples/collections/fxp/SDK_outbound.json +163 -0
- package/examples/collections/hub/hub_01_p2p_happy_path/hub_p2p_receive_quote.json +400 -0
- package/examples/collections/hub/hub_01_p2p_happy_path/hub_p2p_send_quote.json +395 -0
- package/examples/collections/hub/hub_02_block_transfer/hub_block_transfer.json +393 -0
- package/examples/collections/hub/hub_03_funds_in_out/hub_funds_in.json +224 -0
- package/examples/collections/hub/hub_03_funds_in_out/hub_funds_out.json +780 -0
- package/examples/collections/hub/hub_04_settlements/hub_settlements.json +3138 -0
- package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_payee_abort.json +475 -0
- package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_payee_invalid_fulfillment.json +370 -0
- package/examples/collections/hub/hub_05_transfer_negative_scenarios/hub_transfer_negative_transfer_timeout.json +262 -0
- package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_authorizations.json +117 -0
- package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_error_framework.json +591 -0
- package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_received_state.json +379 -0
- package/examples/collections/hub/hub_06_transaction_requests_service/hub_trs_reject_state.json +361 -0
- package/examples/collections/hub/hub_07_quoting_service.json +525 -0
- package/examples/collections/hub/hub_08_participant_inactive_stop_transfers.json +706 -0
- package/examples/collections/hub/hub_09_duplicate_handling_transfers.json +1377 -0
- package/examples/collections/hub/hub_10_on_us_transfers.json +245 -0
- package/examples/collections/hub/hub_11_accented_and_spl_chars.json +629 -0
- package/examples/collections/hub/hub_12_fspiop_version_1.1.json +646 -0
- package/examples/collections/hub/hub_13_bulk_transfers.json +1857 -0
- package/examples/collections/iso20022/self_referencing_iso20022.json +926 -0
- package/examples/collections/provisioning/testingtoolkitdfsp.json +904 -0
- package/examples/environments/dfsp_local_environment.json +46 -0
- package/examples/environments/hub_local_environment.json +57 -0
- package/jest.config.js +17 -0
- package/package.json +199 -0
- package/sbom-v18.12.4.csv +1553 -0
- package/secrets/keygen.sh +5 -0
- package/secrets/privatekey.pem +27 -0
- package/secrets/publickey.cer +21 -0
- package/secrets/tls/01.pem +132 -0
- package/secrets/tls/createSecrets.sh +20 -0
- package/secrets/tls/hub_client.csr +32 -0
- package/secrets/tls/hub_client_cacert.pem +35 -0
- package/secrets/tls/hub_client_cakey.pem +52 -0
- package/secrets/tls/hub_client_key.key +52 -0
- package/secrets/tls/hub_server.csr +31 -0
- package/secrets/tls/hub_server_cacert.pem +35 -0
- package/secrets/tls/hub_server_cakey.pem +52 -0
- package/secrets/tls/hub_server_cert.pem +132 -0
- package/secrets/tls/hub_server_key.key +52 -0
- package/secrets/tls/index.txt +1 -0
- package/secrets/tls/index.txt.attr +1 -0
- package/secrets/tls/openssl-client.cnf +36 -0
- package/secrets/tls/openssl-clientca.cnf +71 -0
- package/secrets/tls/openssl-server.cnf +39 -0
- package/secrets/tls/openssl-serverca.cnf +71 -0
- package/secrets/tls/serial.txt +1 -0
- package/spec_files/api_definitions/als_admin_1.1/api_spec.yaml +804 -0
- package/spec_files/api_definitions/central_admin_1.0/api_spec.yaml +1850 -0
- package/spec_files/api_definitions/central_admin_1.0/response_map.json +96 -0
- package/spec_files/api_definitions/central_admin_old_9.3/api_spec.yaml +2467 -0
- package/spec_files/api_definitions/central_admin_old_9.3/response_map.json +96 -0
- package/spec_files/api_definitions/fspiop_1.0/api_spec.yaml +4187 -0
- package/spec_files/api_definitions/fspiop_1.0/callback_map.json +568 -0
- package/spec_files/api_definitions/fspiop_1.0/mockRef.json +79 -0
- package/spec_files/api_definitions/fspiop_1.0/trigger_templates/transaction_request_followup.json +126 -0
- package/spec_files/api_definitions/fspiop_1.0/trigger_templates/transaction_request_followup_quotes_only.json +97 -0
- package/spec_files/api_definitions/fspiop_1.1/api_spec.yaml +3778 -0
- package/spec_files/api_definitions/fspiop_1.1/callback_map.json +568 -0
- package/spec_files/api_definitions/fspiop_1.1/mockRef.json +79 -0
- package/spec_files/api_definitions/fspiop_1.1/trigger_templates/transaction_request_followup.json +125 -0
- package/spec_files/api_definitions/fspiop_2.0/api_spec.yaml +4839 -0
- package/spec_files/api_definitions/fspiop_2.0/callback_map.json +716 -0
- package/spec_files/api_definitions/fspiop_2.0/mockRef.json +79 -0
- package/spec_files/api_definitions/fspiop_2.0/trigger_templates/transaction_request_followup.json +125 -0
- package/spec_files/api_definitions/fspiop_2.0_iso20022/api_spec.yaml +8331 -0
- package/spec_files/api_definitions/fspiop_2.0_iso20022/callback_map.json +508 -0
- package/spec_files/api_definitions/fspiop_2.0_iso20022/mockRef.json +66 -0
- package/spec_files/api_definitions/fx-api_2.0/api_spec.yaml +1768 -0
- package/spec_files/api_definitions/fx-api_2.0/callback_map.json +188 -0
- package/spec_files/api_definitions/fx-api_2.0/mockRef.json +83 -0
- package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/api_spec.yaml +2612 -0
- package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/mockRef.json +22 -0
- package/spec_files/api_definitions/mojaloop_sdk_outbound_scheme_adapter_1.0/response_map.json +35 -0
- package/spec_files/api_definitions/mojaloop_simulator_0.1/api_spec.yaml +225 -0
- package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/api_spec.yaml +1087 -0
- package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/mockRef.json +75 -0
- package/spec_files/api_definitions/mojaloop_simulator_sim_1.4/response_map.json +55 -0
- package/spec_files/api_definitions/payment_manager_1.4/api_spec.yaml +1389 -0
- package/spec_files/api_definitions/sdk-scheme-adapter-backend-v2_1_0-openapi3-snippets_2.1/api_spec.yaml +2834 -0
- package/spec_files/api_definitions/sdk-scheme-adapter-outbound-v2_1_0-openapi3-snippets_2.1/api_spec.yaml +3449 -0
- package/spec_files/api_definitions/settlements_1.0/api_spec.yaml +983 -0
- package/spec_files/api_definitions/settlements_1.0/mockRef.json +38 -0
- package/spec_files/api_definitions/settlements_1.0/response_map.json +34 -0
- package/spec_files/api_definitions/settlements_2.0/api_spec.yaml +1001 -0
- package/spec_files/api_definitions/settlements_2.0/mockRef.json +38 -0
- package/spec_files/api_definitions/settlements_2.0/response_map.json +34 -0
- package/spec_files/api_definitions/thirdparty_sdk_outbound_0.1/api_spec.yaml +2139 -0
- package/spec_files/reports/templates/newman/html_template.html +1202 -0
- package/spec_files/reports/templates/newman/pdf_template.html +790 -0
- package/spec_files/reports/templates/testcase_definition/table_view.html +1602 -0
- package/spec_files/rules_callback/config.json +3 -0
- package/spec_files/rules_callback/default.json +2698 -0
- package/spec_files/rules_callback/p2p-limit.json +129 -0
- package/spec_files/rules_forward/config.json +3 -0
- package/spec_files/rules_forward/default.json +482 -0
- package/spec_files/rules_response/config.json +3 -0
- package/spec_files/rules_response/default.json +295 -0
- package/spec_files/rules_validation/config.json +3 -0
- package/spec_files/rules_validation/default.json +1 -0
- package/spec_files/rules_validation/p2p-limit.json +55 -0
- package/spec_files/system_config.json +175 -0
- package/spec_files/user_config.json +109 -0
- package/src/index.js +67 -0
- package/src/lib/MyEventEmitter.js +54 -0
- package/src/lib/api-management.js +143 -0
- package/src/lib/api-routes/config.js +83 -0
- package/src/lib/api-routes/history.js +139 -0
- package/src/lib/api-routes/keycloak.js +54 -0
- package/src/lib/api-routes/longpolling.js +70 -0
- package/src/lib/api-routes/oauth2.js +149 -0
- package/src/lib/api-routes/objectstore.js +53 -0
- package/src/lib/api-routes/openapi.js +224 -0
- package/src/lib/api-routes/outbound.js +134 -0
- package/src/lib/api-routes/reports.js +72 -0
- package/src/lib/api-routes/rules.js +356 -0
- package/src/lib/api-routes/samples.js +92 -0
- package/src/lib/api-routes/server-logs.js +44 -0
- package/src/lib/api-routes/settings.js +71 -0
- package/src/lib/api-server.js +135 -0
- package/src/lib/arrayStore.js +101 -0
- package/src/lib/callbackHandler.js +201 -0
- package/src/lib/config.js +177 -0
- package/src/lib/configuration-providers/mb-connection-manager.js +625 -0
- package/src/lib/db/adapters/dbAdapter.js +184 -0
- package/src/lib/db/dfspMockUsers.js +64 -0
- package/src/lib/db/models/mongoDBWrapper.js +78 -0
- package/src/lib/eventListenerClient/inboundEventListener.js +176 -0
- package/src/lib/fileAdapter.js +57 -0
- package/src/lib/httpAgentStore.js +135 -0
- package/src/lib/importExport.js +186 -0
- package/src/lib/jws/JwsSigning.js +141 -0
- package/src/lib/loadSamples.js +128 -0
- package/src/lib/logger.js +20 -0
- package/src/lib/longpollingEmitter.js +56 -0
- package/src/lib/metrics.js +51 -0
- package/src/lib/mocking/custom-functions/generic.js +57 -0
- package/src/lib/mocking/middleware-functions/ilpModel.js +238 -0
- package/src/lib/mocking/middleware-functions/quotesAssociation.js +75 -0
- package/src/lib/mocking/middleware-functions/transactionRequestsService.js +78 -0
- package/src/lib/mocking/openApiDefinitionsModel.js +64 -0
- package/src/lib/mocking/openApiMockHandler.js +466 -0
- package/src/lib/mocking/openApiRulesEngine.js +492 -0
- package/src/lib/mocking/openApiVersionTools.js +136 -0
- package/src/lib/mocking/transformers/fspiopToISO20022.js +230 -0
- package/src/lib/mocking/transformers/index.js +41 -0
- package/src/lib/notificationEmitter.js +64 -0
- package/src/lib/oauth/KeycloakHelper.js +220 -0
- package/src/lib/oauth/LoginService.js +133 -0
- package/src/lib/oauth/OAuthHelper.js +181 -0
- package/src/lib/oauth/OAuthValidator.js +118 -0
- package/src/lib/oauth/Wso2Client.js +64 -0
- package/src/lib/objectStore/inMemoryImpl.js +50 -0
- package/src/lib/objectStore/objectStoreInterface.js +51 -0
- package/src/lib/objectStore.js +122 -0
- package/src/lib/report-generator/generator.js +126 -0
- package/src/lib/report-generator/helpers.js +154 -0
- package/src/lib/requestLogger.js +190 -0
- package/src/lib/resources/wso2carbon-publickey.cert +20 -0
- package/src/lib/rulesEngine.js +95 -0
- package/src/lib/rulesEngineModel.js +463 -0
- package/src/lib/scripting-engines/postman-sandbox.js +142 -0
- package/src/lib/scripting-engines/vm-javascript-sandbox.js +294 -0
- package/src/lib/server-logs/adapters/elastic-search.js +102 -0
- package/src/lib/server-logs/adapters/grafana.js +0 -0
- package/src/lib/server-logs/index.js +75 -0
- package/src/lib/socket-server.js +55 -0
- package/src/lib/storageAdapter.js +109 -0
- package/src/lib/test-outbound/TestCaseRunner.js +173 -0
- package/src/lib/test-outbound/getTracing.js +19 -0
- package/src/lib/test-outbound/outbound-initiator.js +1107 -0
- package/src/lib/uniqueIdGenerator.js +35 -0
- package/src/lib/utils.js +89 -0
- package/src/lib/utilsInternal.js +56 -0
- package/src/lib/webSocketClient/WebSocketClientManager.js +197 -0
- 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
|
+
}
|