@mojaloop/sdk-scheme-adapter 24.7.0 → 24.8.1-snapshot.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/.yarn/cache/{@mojaloop-central-services-shared-npm-18.23.2-5627dda2e3-5fb84a745d.zip → @mojaloop-central-services-shared-npm-18.24.0-34d9578f93-8c24dea9e4.zip} +0 -0
- package/.yarn/cache/@mojaloop-inter-scheme-proxy-cache-lib-npm-2.5.0-eeb80fe407-bf7e14ce33.zip +0 -0
- package/.yarn/cache/{@mojaloop-sdk-standard-components-npm-19.11.2-d6fd02bca7-0cbc9e56e2.zip → @mojaloop-sdk-standard-components-npm-19.14.0-snapshot.3-1229293931-a3faf5f3ac.zip} +0 -0
- package/.yarn/cache/{@types-node-npm-22.14.0-a09e354ed5-8bfae1d3c4.zip → @types-node-npm-22.14.1-ff7e0a29d7-e22363f40a.zip} +0 -0
- package/.yarn/cache/{@typescript-eslint-eslint-plugin-npm-8.29.0-9227710d0b-83475d3a47.zip → @typescript-eslint-eslint-plugin-npm-8.30.1-f4da10f397-dbdc516ad9.zip} +0 -0
- package/.yarn/cache/{@typescript-eslint-parser-npm-8.29.0-510bf7f523-96a1a8cc8a.zip → @typescript-eslint-parser-npm-8.30.1-bcee4d456e-cac3cfe1c1.zip} +0 -0
- package/.yarn/cache/{@typescript-eslint-scope-manager-npm-8.29.0-6046e43075-89a5999ba8.zip → @typescript-eslint-scope-manager-npm-8.30.1-4b479f2d73-cef9e70016.zip} +0 -0
- package/.yarn/cache/{@typescript-eslint-type-utils-npm-8.29.0-1674862818-553fde7826.zip → @typescript-eslint-type-utils-npm-8.30.1-0e1c22c03c-6283d4b4d0.zip} +0 -0
- package/.yarn/cache/@typescript-eslint-types-npm-8.30.1-8bfe1eac21-264c4d8e1b.zip +0 -0
- package/.yarn/cache/{@typescript-eslint-typescript-estree-npm-8.29.0-92fb2cc910-7275c61dc5.zip → @typescript-eslint-typescript-estree-npm-8.30.1-185919bfaf-f57a34e36d.zip} +0 -0
- package/.yarn/cache/{@typescript-eslint-utils-npm-8.29.0-ebf0886c15-81d1afc5de.zip → @typescript-eslint-utils-npm-8.30.1-e8c9d86e99-637b3b8b3d.zip} +0 -0
- package/.yarn/cache/{@typescript-eslint-visitor-keys-npm-8.29.0-e8a9b1561e-d306a7d96b.zip → @typescript-eslint-visitor-keys-npm-8.30.1-e4b2f0ebba-7878f1e3e2.zip} +0 -0
- package/.yarn/cache/dotenv-npm-16.5.0-67343a179e-6543fe87b5.zip +0 -0
- package/.yarn/cache/ioredis-npm-5.6.1-d69383b35a-89100a97b2.zip +0 -0
- package/.yarn/cache/{koa-npm-2.16.0-fccb365a23-01be3231d4.zip → koa-npm-2.16.1-7f26717794-4946d19efb.zip} +0 -0
- package/.yarn/cache/openapi-backend-npm-5.12.0-b2560843ff-0b13c6f128.zip +0 -0
- package/.yarn/cache/{ts-jest-npm-29.3.1-c9a9791a5c-7320bbfab2.zip → ts-jest-npm-29.3.2-cda1b1f7ad-aad8f81ba5.zip} +0 -0
- package/.yarn/cache/{type-fest-npm-4.39.1-227092867f-71ce0e2582.zip → type-fest-npm-4.40.0-18c72d1d94-af2863a707.zip} +0 -0
- package/.yarn/cache/{typescript-npm-5.8.2-b95d637f6a-7f9e3d7ac1.zip → typescript-npm-5.8.3-fbd7aef456-cb1d081c88.zip} +0 -0
- package/.yarn/cache/{typescript-patch-ef570fb450-a58d19ff98.zip → typescript-patch-9106e8a080-1b503525a8.zip} +0 -0
- package/.yarn/cache/yaml-npm-2.7.1-9e92f81b45-385f8115dd.zip +0 -0
- package/.yarn/install-state.gz +0 -0
- package/CHANGELOG.md +7 -0
- package/modules/api-svc/package.json +6 -6
- package/modules/api-svc/src/InboundServer/api.yaml +172 -133
- package/modules/api-svc/src/InboundServer/api_iso20022.yaml +39 -0
- package/modules/api-svc/src/InboundServer/api_template.yaml +170 -66
- package/modules/api-svc/src/InboundServer/handlers.js +26 -6
- package/modules/api-svc/src/InboundServer/index.js +2 -1
- package/modules/api-svc/src/InboundServer/middlewares.js +61 -21
- package/modules/api-svc/src/config.js +1 -0
- package/modules/api-svc/src/lib/model/InboundPingModel.js +100 -0
- package/modules/api-svc/src/lib/model/index.js +3 -2
- package/modules/api-svc/test/__mocks__/@mojaloop/sdk-standard-components.js +2 -0
- package/modules/api-svc/test/unit/lib/model/InboundPingModel.test.js +124 -0
- package/modules/outbound-command-event-handler/package.json +8 -8
- package/modules/outbound-domain-event-handler/package.json +7 -7
- package/modules/private-shared-lib/package.json +7 -7
- package/package.json +6 -6
- package/.yarn/cache/@mojaloop-api-snippets-npm-17.10.1-4e48158984-9a0f1d2fd2.zip +0 -0
- package/.yarn/cache/@mojaloop-central-services-logger-npm-11.7.0-bd1e0d14fc-386d668607.zip +0 -0
- package/.yarn/cache/@mojaloop-inter-scheme-proxy-cache-lib-npm-2.4.0-cc60317958-8e539f65c3.zip +0 -0
- package/.yarn/cache/@mojaloop-ml-schema-transformer-lib-npm-2.7.0-bc64d97e72-bad585bd7d.zip +0 -0
- package/.yarn/cache/@rollup-rollup-linux-x64-musl-npm-4.37.0-51462d4265-8.zip +0 -0
- package/.yarn/cache/@typescript-eslint-types-npm-8.29.0-be9f1bbfb7-30bf710e21.zip +0 -0
|
@@ -1,71 +1,175 @@
|
|
|
1
|
-
openapi: 3.0.
|
|
1
|
+
openapi: 3.0.2
|
|
2
2
|
info:
|
|
3
|
-
version: '
|
|
3
|
+
version: '2.0-draft'
|
|
4
4
|
title: Open API for FSP Interoperability (FSPIOP)
|
|
5
5
|
description: >-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
Revision date: 2023-11-23
|
|
7
|
+
Based on [API Definition updated on 2020-05-19 Version
|
|
8
|
+
1.1](https://github.com/mojaloop/mojaloop-specification/blob/main/documents/v1.1-document-set/API%20Definition_v1.1.pdf).
|
|
9
|
+
|
|
10
|
+
This is implementation friendly version of the API definition.
|
|
11
|
+
|
|
12
|
+
It includes the below definitions needed for third-party functionality.
|
|
13
|
+
- AuthenticationType
|
|
14
|
+
- U2F enum
|
|
15
|
+
- AuthenticationValue
|
|
16
|
+
- oneOf is changed to anyOf
|
|
17
|
+
- new element is added U2FPinValue
|
|
18
|
+
- New element U2FPIN
|
|
19
|
+
|
|
20
|
+
**Note:** The API supports a maximum size of 65536 bytes (64 Kilobytes) in
|
|
21
|
+
the HTTP header.
|
|
9
22
|
license:
|
|
10
|
-
name:
|
|
23
|
+
name: CC BY-ND 4.0
|
|
24
|
+
url: 'https://github.com/mojaloop/mojaloop-specification/blob/main/LICENSE.md'
|
|
25
|
+
contact:
|
|
26
|
+
name: Sam Kummary
|
|
27
|
+
url: 'https://github.com/mojaloop/mojaloop-specification/issues'
|
|
28
|
+
servers:
|
|
29
|
+
- url: 'protocol://hostname:<port>/switch/'
|
|
30
|
+
variables:
|
|
31
|
+
protocol:
|
|
32
|
+
enum:
|
|
33
|
+
- http
|
|
34
|
+
- https
|
|
35
|
+
default: https
|
|
11
36
|
paths:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
37
|
+
/interface:
|
|
38
|
+
post:
|
|
39
|
+
description: >-
|
|
40
|
+
Essential path to include schema definitions that are not used so that
|
|
41
|
+
these definitions get included into the openapi-cli bundle api
|
|
42
|
+
definition so that they get converted into typescript definitions.
|
|
43
|
+
operationId: test
|
|
44
|
+
requestBody:
|
|
45
|
+
content:
|
|
46
|
+
application/json:
|
|
47
|
+
schema:
|
|
48
|
+
oneOf:
|
|
49
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/BinaryString.yaml'
|
|
50
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/BinaryString32.yaml'
|
|
51
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/Date.yaml'
|
|
52
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/Integer.yaml'
|
|
53
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/Name.yaml'
|
|
54
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/PersonalIdentifierType.yaml'
|
|
55
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/TokenCode.yaml'
|
|
56
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/Transaction.yaml'
|
|
57
|
+
- $ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/UndefinedEnum.yaml'
|
|
58
|
+
responses:
|
|
59
|
+
200:
|
|
60
|
+
description: Ok
|
|
61
|
+
/ping:
|
|
62
|
+
post:
|
|
63
|
+
description: The HTTP request `POST /ping` is used to validate mTLS and JWS
|
|
64
|
+
summary: For testing mTLS and JWS
|
|
65
|
+
tags:
|
|
66
|
+
- participants
|
|
67
|
+
- ping
|
|
68
|
+
operationId: handlePostPing
|
|
69
|
+
requestBody:
|
|
70
|
+
description: The object sent in the POST/PUT `/ping` requests with validation request ID.
|
|
71
|
+
required: true
|
|
72
|
+
content:
|
|
73
|
+
application/json:
|
|
74
|
+
schema:
|
|
75
|
+
type: object
|
|
76
|
+
properties:
|
|
77
|
+
requestId:
|
|
78
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/schemas/CorrelationId.yaml'
|
|
79
|
+
required:
|
|
80
|
+
- requestId
|
|
81
|
+
responses:
|
|
82
|
+
'202':
|
|
83
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/202.yaml'
|
|
84
|
+
'400':
|
|
85
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/400.yaml'
|
|
86
|
+
'401':
|
|
87
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/401.yaml'
|
|
88
|
+
'403':
|
|
89
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/403.yaml'
|
|
90
|
+
'404':
|
|
91
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/404.yaml'
|
|
92
|
+
'405':
|
|
93
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/405.yaml'
|
|
94
|
+
'406':
|
|
95
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/406.yaml'
|
|
96
|
+
'501':
|
|
97
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/501.yaml'
|
|
98
|
+
'503':
|
|
99
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/components/responses/503.yaml'
|
|
100
|
+
/participants:
|
|
101
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/participants.yaml'
|
|
102
|
+
/participants/{ID}:
|
|
103
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/participants_ID.yaml'
|
|
104
|
+
/participants/{ID}/error:
|
|
105
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/participants_ID_error.yaml'
|
|
106
|
+
/participants/{Type}/{ID}:
|
|
107
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/participants_Type_ID.yaml'
|
|
108
|
+
/participants/{Type}/{ID}/error:
|
|
109
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/participants_Type_ID_error.yaml'
|
|
110
|
+
/participants/{Type}/{ID}/{SubId}:
|
|
111
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/participants_Type_ID_SubId.yaml'
|
|
112
|
+
/participants/{Type}/{ID}/{SubId}/error:
|
|
113
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/participants_Type_ID_SubId_error.yaml'
|
|
114
|
+
/parties/{Type}/{ID}:
|
|
115
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/parties_Type_ID.yaml'
|
|
116
|
+
/parties/{Type}/{ID}/error:
|
|
117
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/parties_Type_ID_error.yaml'
|
|
118
|
+
/parties/{Type}/{ID}/{SubId}:
|
|
119
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/parties_Type_ID_SubId.yaml'
|
|
120
|
+
/parties/{Type}/{ID}/{SubId}/error:
|
|
121
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/parties_Type_ID_SubId_error.yaml'
|
|
122
|
+
/transactionRequests:
|
|
123
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/transactionRequests.yaml'
|
|
124
|
+
/transactionRequests/{ID}:
|
|
125
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/transactionRequests_ID.yaml'
|
|
126
|
+
/transactionRequests/{ID}/error:
|
|
127
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/transactionRequests_ID_error.yaml'
|
|
128
|
+
/quotes:
|
|
129
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/quotes.yaml'
|
|
130
|
+
/quotes/{ID}:
|
|
131
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/quotes_ID.yaml'
|
|
132
|
+
/quotes/{ID}/error:
|
|
133
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/quotes_ID_error.yaml'
|
|
134
|
+
/authorizations/{ID}:
|
|
135
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/authorizations_ID.yaml'
|
|
136
|
+
/authorizations/{ID}/error:
|
|
137
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/authorizations_ID_error.yaml'
|
|
138
|
+
/transfers:
|
|
139
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/transfers.yaml'
|
|
140
|
+
/transfers/{ID}:
|
|
141
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/transfers_ID.yaml'
|
|
142
|
+
/transfers/{ID}/error:
|
|
143
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/transfers_ID_error.yaml'
|
|
144
|
+
/transactions/{ID}:
|
|
145
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/transactions_ID.yaml'
|
|
146
|
+
/transactions/{ID}/error:
|
|
147
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/transactions_ID_error.yaml'
|
|
148
|
+
/bulkQuotes:
|
|
149
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/bulkQuotes.yaml'
|
|
150
|
+
/bulkQuotes/{ID}:
|
|
151
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/bulkQuotes_ID.yaml'
|
|
152
|
+
/bulkQuotes/{ID}/error:
|
|
153
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/bulkQuotes_ID_error.yaml'
|
|
154
|
+
/bulkTransfers:
|
|
155
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/bulkTransfers.yaml'
|
|
156
|
+
/bulkTransfers/{ID}:
|
|
157
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/bulkTransfers_ID.yaml'
|
|
158
|
+
/bulkTransfers/{ID}/error:
|
|
159
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/bulkTransfers_ID_error.yaml'
|
|
160
|
+
/fxQuotes:
|
|
161
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/fxQuotes.yaml'
|
|
162
|
+
/fxQuotes/{ID}:
|
|
163
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/fxQuotes_ID.yaml'
|
|
164
|
+
/fxQuotes/{ID}/error:
|
|
165
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/fxQuotes_ID_error.yaml'
|
|
166
|
+
/fxTransfers:
|
|
167
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/fxTransfers.yaml'
|
|
168
|
+
/fxTransfers/{ID}:
|
|
169
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/fxTransfers_ID.yaml'
|
|
170
|
+
/fxTransfers/{ID}/error:
|
|
171
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/fxTransfers_ID_error.yaml'
|
|
172
|
+
/services/FXP:
|
|
173
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/services_FXP.yaml'
|
|
174
|
+
/services/FXP/{SourceCurrency}/{TargetCurrency}:
|
|
175
|
+
$ref: '../../../../node_modules/@mojaloop/api-snippets/fspiop/v2_0/openapi3/paths/services_FXP_SourceCurrency_TargetCurrency.yaml'
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
const { Enum } = require('@mojaloop/central-services-shared');
|
|
35
35
|
const {
|
|
36
36
|
InboundTransfersModel,
|
|
37
|
+
InboundPingModel,
|
|
37
38
|
PartiesModel,
|
|
38
39
|
QuotesModel,
|
|
39
40
|
TransfersModel,
|
|
@@ -411,8 +412,8 @@ const putParticipantsByTypeAndId = async (ctx) => {
|
|
|
411
412
|
// publish an event onto the cache for subscribers to action
|
|
412
413
|
let cacheId = `${idType}_${idValue}` + (idSubValue ? `_${idSubValue}` : '');
|
|
413
414
|
const message = { data };
|
|
414
|
-
|
|
415
|
-
// We need to determine if this callback is a response to either a GET/POST /participants
|
|
415
|
+
|
|
416
|
+
// We need to determine if this callback is a response to either a GET/POST /participants
|
|
416
417
|
// or DELETE /participants/{Type}/{ID}/{SubId} request
|
|
417
418
|
const adCacheId = `ad_${cacheId}`;
|
|
418
419
|
if (ctx.state.cache._callbacks[adCacheId]) {
|
|
@@ -431,8 +432,8 @@ const putParticipantsByTypeAndId = async (ctx) => {
|
|
|
431
432
|
|
|
432
433
|
|
|
433
434
|
/**
|
|
434
|
-
* Handles a PUT /participants/{Type}/{ID}/{SubId}/error request.
|
|
435
|
-
* This is an error response to a GET /participants/{Type}/{ID}/{SubId} or
|
|
435
|
+
* Handles a PUT /participants/{Type}/{ID}/{SubId}/error request.
|
|
436
|
+
* This is an error response to a GET /participants/{Type}/{ID}/{SubId} or
|
|
436
437
|
* DELETE /participants/{Type}/{ID}/{SubId} request
|
|
437
438
|
*/
|
|
438
439
|
const putParticipantsByTypeAndIdError = async(ctx) => {
|
|
@@ -450,7 +451,7 @@ const putParticipantsByTypeAndIdError = async(ctx) => {
|
|
|
450
451
|
let cacheId = `${idType}_${idValue}` + (idSubValue ? `_${idSubValue}` : '');
|
|
451
452
|
const message = { data };
|
|
452
453
|
|
|
453
|
-
// We need to determine if this callback is a response to either a GET/POST /participants
|
|
454
|
+
// We need to determine if this callback is a response to either a GET/POST /participants
|
|
454
455
|
// or DELETE /participants/{Type}/{ID}/{SubId} request
|
|
455
456
|
const adCacheId = `ad_${cacheId}`;
|
|
456
457
|
if (ctx.state.cache._callbacks[adCacheId]) {
|
|
@@ -1105,6 +1106,22 @@ const createPutFxTransfersHandler = (success) => async (ctx) => {
|
|
|
1105
1106
|
ctx.response.status = ReturnCodes.OK.CODE;
|
|
1106
1107
|
};
|
|
1107
1108
|
|
|
1109
|
+
const handlePostPing = (ctx) => {
|
|
1110
|
+
const { jwsPingValidationResult, conf, logger, wso2 } = ctx.state;
|
|
1111
|
+
const { sourceFspId, body, headers } = extractBodyHeadersSourceFspId(ctx);
|
|
1112
|
+
|
|
1113
|
+
const model = new InboundPingModel({
|
|
1114
|
+
...conf,
|
|
1115
|
+
resourceVersions: ctx.resourceVersions,
|
|
1116
|
+
logger,
|
|
1117
|
+
wso2,
|
|
1118
|
+
});
|
|
1119
|
+
model.postPing({ jwsPingValidationResult, sourceFspId, body, headers })
|
|
1120
|
+
.catch(err => logger.error('error in handlePostPing:', err));
|
|
1121
|
+
|
|
1122
|
+
prepareResponse(ctx);
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1108
1125
|
module.exports = {
|
|
1109
1126
|
'/': {
|
|
1110
1127
|
get: healthCheck
|
|
@@ -1217,5 +1234,8 @@ module.exports = {
|
|
|
1217
1234
|
},
|
|
1218
1235
|
'/fxTransfers/{ID}/error': {
|
|
1219
1236
|
put: createPutFxTransfersHandler(false)
|
|
1220
|
-
}
|
|
1237
|
+
},
|
|
1238
|
+
'/ping': {
|
|
1239
|
+
post: handlePostPing
|
|
1240
|
+
},
|
|
1221
1241
|
};
|
|
@@ -125,7 +125,8 @@ class InboundApi extends EventEmitter {
|
|
|
125
125
|
api.use(middlewares.createJwsValidator(logger, jwsVerificationKeys, jwsExclusions));
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
api.use(middlewares.applyState({ cache, wso2,
|
|
128
|
+
api.use(middlewares.applyState({ conf, cache, wso2, logExcludePaths }));
|
|
129
|
+
api.use(middlewares.createPingMiddleware(conf, jwsVerificationKeys));
|
|
129
130
|
api.use(middlewares.createRequestValidator(validator));
|
|
130
131
|
api.use(middlewares.assignFspiopIdentifier());
|
|
131
132
|
if (conf.enableTestFeatures) {
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
--------------
|
|
26
26
|
******/
|
|
27
27
|
const { env } = require('node:process');
|
|
28
|
-
const coBody = require('co-body');
|
|
29
28
|
const { generateSlug } = require('random-word-slugs');
|
|
29
|
+
const coBody = require('co-body');
|
|
30
30
|
|
|
31
31
|
const { Jws, Errors, common } = require('@mojaloop/sdk-standard-components');
|
|
32
32
|
const { ReturnCodes } = require('@mojaloop/central-services-shared').Enum.Http;
|
|
@@ -58,7 +58,7 @@ const createErrorHandler = (logger) => async (ctx, next) => {
|
|
|
58
58
|
await next();
|
|
59
59
|
} catch (err) {
|
|
60
60
|
// TODO: return a 500 here if the response has not already been sent?
|
|
61
|
-
logger.
|
|
61
|
+
logger.error('Error caught in catchall: ', err);
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
|
|
@@ -261,7 +261,7 @@ const createHeaderValidator = (conf) => async (
|
|
|
261
261
|
|
|
262
262
|
// Only validate requests for the requested resources
|
|
263
263
|
if (!resources.includes(resource)) {
|
|
264
|
-
logger.info(`
|
|
264
|
+
logger.info(`skipping header validation for ${resource}`);
|
|
265
265
|
return await next();
|
|
266
266
|
}
|
|
267
267
|
|
|
@@ -347,17 +347,9 @@ const createHeaderValidator = (conf) => async (
|
|
|
347
347
|
return;
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
catch(err) {
|
|
354
|
-
// error parsing body
|
|
355
|
-
logger.push({ err }).error('Error parsing body');
|
|
356
|
-
ctx.response.status = Errors.MojaloopApiErrorCodes.MALFORMED_SYNTAX.httpStatusCode;
|
|
357
|
-
ctx.response.body = new Errors.MojaloopFSPIOPError(err, err.message, null,
|
|
358
|
-
Errors.MojaloopApiErrorCodes.MALFORMED_SYNTAX).toApiErrorObject();
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
350
|
+
const isOk = await extractRequestBody(conf, ctx);
|
|
351
|
+
if (!isOk) return;
|
|
352
|
+
|
|
361
353
|
await next();
|
|
362
354
|
};
|
|
363
355
|
|
|
@@ -372,7 +364,7 @@ const createHeaderValidator = (conf) => async (
|
|
|
372
364
|
const createJwsValidator = (logger, keys, exclusions) => {
|
|
373
365
|
// todo: take logger from ctx
|
|
374
366
|
const jwsValidator = new Jws.validator({
|
|
375
|
-
logger
|
|
367
|
+
logger,
|
|
376
368
|
validationKeys: keys,
|
|
377
369
|
});
|
|
378
370
|
// JWS validation for incoming requests
|
|
@@ -383,22 +375,23 @@ const createJwsValidator = (logger, keys, exclusions) => {
|
|
|
383
375
|
if (exclusions.includes('putParties')
|
|
384
376
|
&& ctx.request.method === 'PUT'
|
|
385
377
|
&& ctx.request.path.startsWith('/parties/')) {
|
|
386
|
-
logger.
|
|
378
|
+
logger.info('skipping jws validation on put parties. config flag is set');
|
|
387
379
|
return await next();
|
|
388
380
|
}
|
|
389
381
|
|
|
382
|
+
if (isPingRoute(ctx)) return await next();
|
|
383
|
+
|
|
390
384
|
// we dont check signatures on GET requests
|
|
391
385
|
// todo: validate this requirement. No state is mutated by GETs but
|
|
392
386
|
// there are potential security issues if message origin is used to
|
|
393
387
|
// determine permission sets i.e. what is "readable"
|
|
394
388
|
if (ctx.request.method !== 'GET') {
|
|
395
389
|
logger.isDebugEnabled && logger.push({ request: ctx.request, body: ctx.request.body }).debug('Validating JWS');
|
|
396
|
-
jwsValidator.validate(ctx.request
|
|
390
|
+
jwsValidator.validate(ctx.request);
|
|
397
391
|
}
|
|
398
392
|
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
logger.push({ err }).error('Inbound request failed JWS validation');
|
|
393
|
+
} catch (err) {
|
|
394
|
+
logger.error('Inbound request failed JWS validation', err);
|
|
402
395
|
|
|
403
396
|
ctx.response.status = ReturnCodes.BADREQUEST.CODE;
|
|
404
397
|
ctx.response.body = new Errors.MojaloopFSPIOPError(
|
|
@@ -445,7 +438,6 @@ const createLogger = (logger) => async (ctx, next) => {
|
|
|
445
438
|
await next();
|
|
446
439
|
};
|
|
447
440
|
|
|
448
|
-
|
|
449
441
|
/**
|
|
450
442
|
* Add validation for each inbound request
|
|
451
443
|
* @param validator
|
|
@@ -516,6 +508,53 @@ const createResponseLogging = () => async (ctx, next) => {
|
|
|
516
508
|
return await next();
|
|
517
509
|
};
|
|
518
510
|
|
|
511
|
+
const createPingMiddleware = (config, validationKeys) => async (ctx, next) => {
|
|
512
|
+
if (!isPingRoute(ctx)) return await next();
|
|
513
|
+
|
|
514
|
+
const { logger } = ctx.state;
|
|
515
|
+
const isOk = await extractRequestBody(config, ctx);
|
|
516
|
+
if (!isOk) {
|
|
517
|
+
logger.warn('failed to extract request body');
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
let result;
|
|
522
|
+
|
|
523
|
+
if (validationKeys) {
|
|
524
|
+
const jwsValidator = new Jws.validator({
|
|
525
|
+
logger,
|
|
526
|
+
validationKeys,
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
try {
|
|
530
|
+
result = jwsValidator.validate(ctx.request);
|
|
531
|
+
} catch (err) {
|
|
532
|
+
result = err;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
ctx.state.jwsPingValidationResult = result;
|
|
537
|
+
logger.verbose(`is jwsPingValidation passed: ${result === true}`);
|
|
538
|
+
|
|
539
|
+
await next();
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
const extractRequestBody = async (conf, ctx) => {
|
|
543
|
+
try {
|
|
544
|
+
ctx.request.body = await coBody.json(ctx.req, { limit: conf.fspiopApiServerMaxRequestBytes });
|
|
545
|
+
return true;
|
|
546
|
+
} catch (err) {
|
|
547
|
+
// error parsing body
|
|
548
|
+
ctx.state.logger.error('Error parsing body: ', err);
|
|
549
|
+
ctx.response.status = Errors.MojaloopApiErrorCodes.MALFORMED_SYNTAX.httpStatusCode;
|
|
550
|
+
ctx.response.body = new Errors.MojaloopFSPIOPError(err, err.message, null,
|
|
551
|
+
Errors.MojaloopApiErrorCodes.MALFORMED_SYNTAX).toApiErrorObject();
|
|
552
|
+
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
const isPingRoute = (ctx) => ctx.request?.path?.startsWith('/ping');
|
|
557
|
+
|
|
519
558
|
module.exports = {
|
|
520
559
|
applyState,
|
|
521
560
|
assignFspiopIdentifier,
|
|
@@ -528,5 +567,6 @@ module.exports = {
|
|
|
528
567
|
createRequestValidator,
|
|
529
568
|
createResponseBodyHandler,
|
|
530
569
|
createResponseLogging,
|
|
570
|
+
createPingMiddleware,
|
|
531
571
|
logResponse,
|
|
532
572
|
};
|
|
@@ -157,6 +157,7 @@ module.exports = {
|
|
|
157
157
|
bulkTransfersEndpoint: env.get('BULK_TRANSFERS_ENDPOINT').asString(),
|
|
158
158
|
fxQuotesEndpoint: env.get('FX_QUOTES_ENDPOINT').asString(),
|
|
159
159
|
fxTransfersEndpoint: env.get('FX_TRANSFERS_ENDPOINT').asString(),
|
|
160
|
+
pingEndpoint: env.get('PING_ENDPOINT').asString(),
|
|
160
161
|
backendEndpoint: env.get('BACKEND_ENDPOINT').required().asString(),
|
|
161
162
|
|
|
162
163
|
getServicesFxpResponse: env.get('GET_SERVICES_FXP_RESPONSE').default('').asArray(),
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
* Eugen Klymniuk <eugen.klymniuk@infitx.com>
|
|
24
|
+
|
|
25
|
+
--------------
|
|
26
|
+
******/
|
|
27
|
+
|
|
28
|
+
const { requests: { PingRequests }, Errors } = require('@mojaloop/sdk-standard-components');
|
|
29
|
+
const { Headers } = require('@mojaloop/central-services-shared').Enum.Http;
|
|
30
|
+
|
|
31
|
+
class InboundPingModel {
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.logger = config.logger.push({ component: this.constructor.name });
|
|
34
|
+
this.dfspId = config.dfspId;
|
|
35
|
+
this.pingRequests = new PingRequests({
|
|
36
|
+
logger: this.logger,
|
|
37
|
+
peerEndpoint: config.peerEndpoint,
|
|
38
|
+
pingEndpoint: config.pingEndpoint,
|
|
39
|
+
dfspId: config.dfspId,
|
|
40
|
+
tls: {
|
|
41
|
+
enabled: config.outbound.tls.mutualTLS.enabled,
|
|
42
|
+
creds: config.outbound.tls.creds,
|
|
43
|
+
},
|
|
44
|
+
jwsSign: config.jwsSign,
|
|
45
|
+
jwsSigningKey: config.jwsSigningKey,
|
|
46
|
+
// todo: think, if we need the rest
|
|
47
|
+
wso2: config.wso2,
|
|
48
|
+
resourceVersions: config.resourceVersions,
|
|
49
|
+
apiType: config.apiType,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async postPing({ jwsPingValidationResult, sourceFspId, body, headers }) {
|
|
54
|
+
const { requestId } = body;
|
|
55
|
+
const log = this.logger.child({ requestId, sourceFspId });
|
|
56
|
+
log.debug('postPing...', { jwsPingValidationResult, headers });
|
|
57
|
+
|
|
58
|
+
if (jwsPingValidationResult === true) {
|
|
59
|
+
log.verbose('ping JWS validation passed, sending PUT ping callback...');
|
|
60
|
+
return this.pingRequests.putPing({
|
|
61
|
+
requestId,
|
|
62
|
+
destination: sourceFspId,
|
|
63
|
+
headers: this.#createCallbackHeaders(headers),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const errInfo = this.#createPingError(jwsPingValidationResult);
|
|
68
|
+
log.info('ping JWS validation failed, sending PUT ping error callback...', { errInfo });
|
|
69
|
+
return this.pingRequests.putPingError({
|
|
70
|
+
requestId,
|
|
71
|
+
destination: sourceFspId,
|
|
72
|
+
headers: this.#createCallbackHeaders(headers),
|
|
73
|
+
errInfo
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#createPingError(jwsPingValidationResult, destination) {
|
|
78
|
+
const cause = jwsPingValidationResult || new Error('JWS validationKeys are not provided');
|
|
79
|
+
const errMessage = 'error on JWS ping validation';
|
|
80
|
+
const fspiopError = new Errors.MojaloopFSPIOPError(
|
|
81
|
+
cause,
|
|
82
|
+
errMessage,
|
|
83
|
+
destination,
|
|
84
|
+
Errors.MojaloopApiErrorCodes.VALIDATION_ERROR
|
|
85
|
+
);
|
|
86
|
+
this.logger.warn(`${errMessage}: ${cause.message}`);
|
|
87
|
+
|
|
88
|
+
return fspiopError.toApiErrorObject();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#createCallbackHeaders(headers) {
|
|
92
|
+
return {
|
|
93
|
+
...headers,
|
|
94
|
+
[Headers.FSPIOP.DESTINATION]: headers[Headers.FSPIOP.SOURCE],
|
|
95
|
+
[Headers.FSPIOP.SOURCE]: this.dfspId
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = InboundPingModel;
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
******/
|
|
27
27
|
'use strict';
|
|
28
28
|
|
|
29
|
-
|
|
30
29
|
const InboundTransfersModel = require('./InboundTransfersModel');
|
|
30
|
+
const InboundPingModel = require('./InboundPingModel');
|
|
31
31
|
const OutboundTransfersModel = require('./OutboundTransfersModel');
|
|
32
32
|
const OutboundBulkQuotesModel = require('./OutboundBulkQuotesModel');
|
|
33
33
|
const OutboundBulkTransfersModel = require('./OutboundBulkTransfersModel');
|
|
@@ -43,11 +43,12 @@ const TransfersModel = require('./TransfersModel');
|
|
|
43
43
|
module.exports = {
|
|
44
44
|
AccountsModel,
|
|
45
45
|
BackendError,
|
|
46
|
+
InboundTransfersModel,
|
|
47
|
+
InboundPingModel,
|
|
46
48
|
OutboundBulkQuotesModel,
|
|
47
49
|
OutboundBulkTransfersModel,
|
|
48
50
|
OutboundRequestToPayTransferModel,
|
|
49
51
|
OutboundRequestToPayModel,
|
|
50
|
-
InboundTransfersModel,
|
|
51
52
|
OutboundTransfersModel,
|
|
52
53
|
ProxyModel,
|
|
53
54
|
PersistentStateMachine,
|
|
@@ -33,6 +33,7 @@ const {
|
|
|
33
33
|
axios,
|
|
34
34
|
MojaloopRequests, Errors, WSO2Auth, Jws, Logger, common,
|
|
35
35
|
httpRequester,
|
|
36
|
+
requests: { PingRequests },
|
|
36
37
|
Ilp: { ILP_VERSIONS }
|
|
37
38
|
} = jest.requireActual('@mojaloop/sdk-standard-components');
|
|
38
39
|
|
|
@@ -200,6 +201,7 @@ module.exports = {
|
|
|
200
201
|
axios,
|
|
201
202
|
Ilp,
|
|
202
203
|
httpRequester,
|
|
204
|
+
requests: { PingRequests },
|
|
203
205
|
MojaloopRequests: MockMojaloopRequests,
|
|
204
206
|
Jws: {
|
|
205
207
|
validator: MockJwsValidator,
|