account-lookup-service 15.6.0-iso.2 → 15.6.0-iso.21

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 (53) hide show
  1. package/.circleci/config.yml +1 -1
  2. package/.ncurc.yaml +1 -2
  3. package/audit-ci.jsonc +3 -1
  4. package/jest.config.js +2 -0
  5. package/package.json +15 -17
  6. package/src/constants.js +2 -1
  7. package/src/domain/oracle/oracle.js +63 -4
  8. package/src/domain/participants/participants.js +259 -133
  9. package/src/domain/parties/getPartiesByTypeAndID.js +36 -15
  10. package/src/domain/parties/parties.js +44 -14
  11. package/src/domain/parties/utils.js +13 -6
  12. package/src/domain/timeout/dto.js +4 -10
  13. package/src/domain/timeout/index.js +12 -1
  14. package/src/handlers/index.js +4 -4
  15. package/src/handlers/monitoring/index.js +1 -1
  16. package/src/interface/api-swagger-iso20022-parties.yaml +7 -6
  17. package/src/interface/api-swagger.yaml +7 -6
  18. package/src/interface/fspiop-rest-v2.0-ISO20022_parties.yaml +2043 -1583
  19. package/src/lib/config.js +1 -1
  20. package/src/lib/index.js +1 -2
  21. package/src/models/currency/currency.js +10 -1
  22. package/src/models/endpointType/endpointType.js +10 -1
  23. package/src/models/oracle/facade.js +24 -3
  24. package/src/models/oracle/oracleEndpoint.js +64 -10
  25. package/src/models/oracle/oracleEndpointCached.js +22 -3
  26. package/src/models/participantEndpoint/facade.js +61 -23
  27. package/src/models/partyIdType/partyIdType.js +10 -1
  28. package/src/plugins.js +20 -9
  29. package/src/server.js +11 -19
  30. package/test/fixtures/index.js +30 -6
  31. package/test/fixtures/iso.js +1 -1
  32. package/test/unit/api/health.test.js +3 -0
  33. package/test/unit/api/participants/participants.test.js +5 -7
  34. package/test/unit/api/participants/{Type}/{ID}/{SubId}.test.js +0 -3
  35. package/test/unit/api/participants/{Type}/{ID}.test.js +0 -3
  36. package/test/unit/api/participants.test.js +36 -3
  37. package/test/unit/domain/oracle/oracle.test.js +8 -0
  38. package/test/unit/domain/participants/participants.test.js +83 -48
  39. package/test/unit/domain/parties/parties.test.js +11 -3
  40. package/test/unit/domain/parties/utils.test.js +60 -0
  41. package/test/unit/domain/timeout/dto.test.js +1 -2
  42. package/test/unit/domain/timeout/index.test.js +8 -0
  43. package/test/unit/lib/TransformFacades.test.js +2 -1
  44. package/test/unit/lib/config.test.js +7 -0
  45. package/test/unit/models/participantEndpoint/facade.test.js +25 -8
  46. package/test/unit/plugins.test.js +4 -2
  47. package/test/util/apiClients/BasicApiClient.js +2 -2
  48. package/src/handlers/monitoring/plugins/metrics.js +0 -48
  49. package/src/lib/requestLogger.js +0 -54
  50. package/src/metrics/handler.js +0 -33
  51. package/src/metrics/plugin.js +0 -52
  52. package/src/metrics/routes.js +0 -43
  53. package/test/unit/lib/requestLogger.test.js +0 -115
@@ -1,7 +1,7 @@
1
1
  version: 2.1
2
2
  setup: true
3
3
  orbs:
4
- build: mojaloop/build@1.0.25
4
+ build: mojaloop/build@1.0.27
5
5
  workflows:
6
6
  setup:
7
7
  jobs:
package/.ncurc.yaml CHANGED
@@ -1,6 +1,5 @@
1
1
  ## Add a TODO comment indicating the reason for each rejected dependency upgrade added to this list, and what should be done to resolve it (i.e. handle it through a story, etc).
2
2
  reject: [
3
3
  # TODO: v6+ (ref: https://github.com/sindresorhus/get-port/releases/tag/v6.0.0) is an ESM library and thus not compatible with CommonJS. Future story needed to resolve.
4
- "get-port",
5
- "@mojaloop/central-services-shared" ## need to remove before merging proxyCache functionality to main
4
+ "get-port"
6
5
  ]
package/audit-ci.jsonc CHANGED
@@ -27,6 +27,8 @@
27
27
  "GHSA-7fh5-64p2-3v2j",
28
28
  "GHSA-rm97-x556-q36h", // https://github.com/advisories/GHSA-rm97-x556-q36h
29
29
  "GHSA-rv95-896h-c2vc", // https://github.com/advisories/GHSA-rv95-896h-c2vc
30
- "GHSA-952p-6rrq-rcjv" // https://github.com/advisories/GHSA-952p-6rrq-rcjv
30
+ "GHSA-952p-6rrq-rcjv", // https://github.com/advisories/GHSA-952p-6rrq-rcjv
31
+ "GHSA-3xgq-45jj-v275", // https://github.com/advisories/GHSA-3xgq-45jj-v275
32
+ "GHSA-rhx6-c78j-4q9w" // https://github.com/advisories/GHSA-rhx6-c78j-4q9w
31
33
  ]
32
34
  }
package/jest.config.js CHANGED
@@ -1,5 +1,7 @@
1
1
  module.exports = {
2
2
  verbose: true,
3
+ clearMocks: true,
4
+
3
5
  collectCoverageFrom: [
4
6
  '**/src/**/**/*.js'
5
7
  ],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "account-lookup-service",
3
3
  "description": "Account Lookup Service is used to validate Party and Participant lookups.",
4
- "version": "15.6.0-iso.2",
4
+ "version": "15.6.0-iso.21",
5
5
  "license": "Apache-2.0",
6
6
  "author": "ModusBox",
7
7
  "contributors": [
@@ -54,7 +54,7 @@
54
54
  "test:coverage-check": "npm test -- --coverage",
55
55
  "test:junit": "npm test -- --reporters=default --reporters=jest-junit",
56
56
  "test:xunit": "npm run test:junit",
57
- "test:functional": "sh ./scripts/test-functional.sh",
57
+ "test:functional": "bash ./scripts/test-functional.sh",
58
58
  "test:int": "npm run migrate && npm run onboarding && jest --config=./jest-int.config.js --runInBand",
59
59
  "test:integration": "npm run dc:up && npm run wait-4-docker && npm run test:int | tee ./test/results/test-int.log",
60
60
  "test:integration-runner": "TEST_MODE=rm ./test/integration-runner.sh",
@@ -87,27 +87,26 @@
87
87
  "@hapi/boom": "10.0.1",
88
88
  "@hapi/catbox-memory": "6.0.2",
89
89
  "@hapi/good": "9.0.1",
90
- "@hapi/hapi": "21.3.10",
90
+ "@hapi/hapi": "21.3.12",
91
91
  "@hapi/inert": "7.1.0",
92
- "@hapi/joi": "17.1.1",
93
92
  "@hapi/vision": "7.0.3",
94
- "@mojaloop/central-services-error-handling": "13.0.1",
93
+ "@mojaloop/central-services-error-handling": "13.0.2",
95
94
  "@mojaloop/central-services-health": "15.0.0",
96
95
  "@mojaloop/central-services-logger": "11.5.1",
97
- "@mojaloop/central-services-metrics": "12.0.8",
98
- "@mojaloop/central-services-shared": "18.10.0-snapshot.4",
96
+ "@mojaloop/central-services-metrics": "12.4.2",
97
+ "@mojaloop/central-services-shared": "18.14.1",
99
98
  "@mojaloop/central-services-stream": "11.3.1",
100
99
  "@mojaloop/database-lib": "11.0.6",
101
100
  "@mojaloop/event-sdk": "14.1.1",
102
- "@mojaloop/inter-scheme-proxy-cache-lib": "2.3.0",
103
- "@mojaloop/ml-schema-transformer-lib": "1.1.1",
104
- "@mojaloop/sdk-standard-components": "19.0.0",
101
+ "@mojaloop/inter-scheme-proxy-cache-lib": "2.3.1",
102
+ "@mojaloop/ml-schema-transformer-lib": "2.4.1",
103
+ "@mojaloop/sdk-standard-components": "19.6.2",
105
104
  "@now-ims/hapi-now-auth": "2.1.0",
106
105
  "ajv": "8.17.1",
107
106
  "ajv-keywords": "5.1.0",
108
107
  "blipp": "4.0.2",
109
108
  "commander": "12.1.0",
110
- "cron": "3.1.7",
109
+ "cron": "3.3.1",
111
110
  "fast-safe-stringify": "^2.1.1",
112
111
  "hapi-auth-bearer-token": "8.0.0",
113
112
  "joi": "17.13.3",
@@ -147,22 +146,21 @@
147
146
  "jsonpointer": "5.0.0"
148
147
  },
149
148
  "devDependencies": {
150
- "@types/jest": "29.5.13",
149
+ "@types/jest": "29.5.14",
151
150
  "audit-ci": "^7.1.0",
152
- "axios": "1.7.7",
151
+ "axios": "1.7.9",
153
152
  "axios-retry": "^4.5.0",
154
153
  "docdash": "2.0.2",
155
- "dotenv": "^16.4.5",
154
+ "dotenv": "^16.4.7",
156
155
  "get-port": "5.1.1",
157
156
  "ioredis-mock": "^8.9.0",
158
157
  "jest": "29.7.0",
159
158
  "jest-junit": "16.0.0",
160
- "jsdoc": "4.0.3",
159
+ "jsdoc": "4.0.4",
161
160
  "nodemon": "3.1.7",
162
- "npm-check-updates": "17.1.4",
161
+ "npm-check-updates": "17.1.11",
163
162
  "nyc": "17.1.0",
164
163
  "pre-commit": "1.2.2",
165
- "proxyquire": "2.1.3",
166
164
  "replace": "^1.2.2",
167
165
  "sinon": "19.0.2",
168
166
  "standard": "17.1.2",
package/src/constants.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const ERROR_MESSAGES = Object.freeze({
2
- partySourceFspNotFound: 'Requester FSP not found',
2
+ sourceFspNotFound: 'Requester FSP not found',
3
+ partySourceFspNotFound: 'Requester FSP not found', // todo: use sourceFspNotFound
3
4
  partyDestinationFspNotFound: 'Destination FSP not found',
4
5
  partyProxyNotFound: 'Proxy not found',
5
6
  proxyConnectionError: 'Proxy connection error',
@@ -49,9 +49,15 @@ exports.createOracle = async (payload) => {
49
49
  'Create Oracle',
50
50
  ['success']
51
51
  ).startTimer()
52
+ const errorCounter = Metrics.getCounter('errorCount')
53
+ let step
54
+
52
55
  try {
56
+ step = 'getPartyIdTypeByName-1'
53
57
  const partyIdTypeModel = await partyIdType.getPartyIdTypeByName(payload.oracleIdType)
58
+ step = 'getEndpointTypeByType-2'
54
59
  const endpointTypeModel = await endpointType.getEndpointTypeByType(payload.endpoint.endpointType)
60
+ step = 'getAllOracleEndpointsByMatchCondition-3'
55
61
  const existingActiveOracle = await oracleEndpoint.getAllOracleEndpointsByMatchCondition(
56
62
  payload,
57
63
  partyIdTypeModel.partyIdTypeId,
@@ -77,13 +83,23 @@ exports.createOracle = async (payload) => {
77
83
  oracleEntity.createdBy = 'Admin'
78
84
  oracleEntity.partyIdTypeId = partyIdTypeModel.partyIdTypeId
79
85
  oracleEntity.endpointTypeId = endpointTypeModel.endpointTypeId
86
+ step = 'createOracleEndpoint-4'
80
87
  await oracleEndpoint.createOracleEndpoint(oracleEntity)
81
88
  histTimerEnd({ success: true })
82
89
  return true
83
90
  } catch (err) {
84
91
  histTimerEnd({ success: false })
85
92
  Logger.isErrorEnabled && Logger.error(err)
86
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
93
+ const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
94
+ const extensions = err.extensions || []
95
+ const system = extensions.find((element) => element.key === 'system')?.value || ''
96
+ errorCounter.inc({
97
+ code: fspiopError?.apiErrorCode,
98
+ system,
99
+ operation: 'createOracle',
100
+ step
101
+ })
102
+ throw fspiopError
87
103
  }
88
104
  }
89
105
 
@@ -100,6 +116,8 @@ exports.getOracle = async (query) => {
100
116
  'Get Oracle',
101
117
  ['success']
102
118
  ).startTimer()
119
+ const errorCounter = Metrics.getCounter('errorCount')
120
+ let step
103
121
  try {
104
122
  let oracleEndpointModelList
105
123
  let isCurrency; let isType = false
@@ -111,12 +129,16 @@ exports.getOracle = async (query) => {
111
129
  isType = true
112
130
  }
113
131
  if (isCurrency && isType) {
132
+ step = 'getOracleEndpointByTypeAndCurrency-1'
114
133
  oracleEndpointModelList = await cachedOracleEndpoint.getOracleEndpointByTypeAndCurrency(query.type, query.currency)
115
134
  } else if (isCurrency && !isType) {
135
+ step = 'getOracleEndpointByCurrency-2'
116
136
  oracleEndpointModelList = await cachedOracleEndpoint.getOracleEndpointByCurrency(query.currency)
117
137
  } else if (isType && !isCurrency) {
138
+ step = 'getOracleEndpointByType-3'
118
139
  oracleEndpointModelList = await cachedOracleEndpoint.getOracleEndpointByType(query.type)
119
140
  } else {
141
+ step = 'getAllOracleEndpoint-4'
120
142
  oracleEndpointModelList = await oracleEndpoint.getAllOracleEndpoint()
121
143
  }
122
144
  for (const oracleEndpointModel of oracleEndpointModelList) {
@@ -137,7 +159,16 @@ exports.getOracle = async (query) => {
137
159
  } catch (err) {
138
160
  histTimerEnd({ success: false })
139
161
  Logger.isErrorEnabled && Logger.error(err)
140
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
162
+ const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
163
+ const extensions = err.extensions || []
164
+ const system = extensions.find((element) => element.key === 'system')?.value || ''
165
+ errorCounter.inc({
166
+ code: fspiopError?.apiErrorCode,
167
+ system,
168
+ operation: 'getOracle',
169
+ step
170
+ })
171
+ throw fspiopError
141
172
  }
142
173
  }
143
174
 
@@ -155,11 +186,17 @@ exports.updateOracle = async (params, payload) => {
155
186
  'Update Oracle',
156
187
  ['success']
157
188
  ).startTimer()
189
+ const errorCounter = Metrics.getCounter('errorCount')
190
+ let step
158
191
  try {
192
+ step = 'getOracleEndpointById-1'
159
193
  const currentOracleEndpointList = await oracleEndpoint.getOracleEndpointById(params.ID)
160
194
  if (currentOracleEndpointList.length > 0) {
195
+ step = 'getPartyIdTypeByName-2'
161
196
  const partyIdTypeModel = await partyIdType.getPartyIdTypeByName(payload.oracleIdType)
197
+ step = 'getEndpointTypeByType-3'
162
198
  const endpointTypeModel = await endpointType.getEndpointTypeByType(payload.endpoint.endpointType)
199
+ step = 'getAllOracleEndpointsByMatchCondition-4'
163
200
  const existingActiveOracle = await oracleEndpoint.getAllOracleEndpointsByMatchCondition(
164
201
  payload,
165
202
  partyIdTypeModel.partyIdTypeId,
@@ -175,6 +212,7 @@ exports.updateOracle = async (params, payload) => {
175
212
  const currentOracleEndpoint = currentOracleEndpointList[0]
176
213
  const newOracleEntry = {}
177
214
  if (payload.oracleIdType && payload.oracleIdType !== currentOracleEndpoint.idType) {
215
+ step = 'getPartyIdTypeByName-5'
178
216
  const partyTypeModel = await partyIdType.getPartyIdTypeByName(payload.oracleIdType)
179
217
  newOracleEntry.partyIdTypeId = partyTypeModel.partyIdTypeId
180
218
  }
@@ -182,10 +220,12 @@ exports.updateOracle = async (params, payload) => {
182
220
  newOracleEntry.value = payload.endpoint.value
183
221
  }
184
222
  if (payload.endpoint && payload.endpoint.endpointType && payload.endpoint.endpointType !== currentOracleEndpoint.endpointType) {
223
+ step = 'getEndpointTypeByType-6'
185
224
  const endpointTypeModel = await endpointType.getEndpointTypeByType(payload.endpoint.endpointType)
186
225
  newOracleEntry.endpointTypeId = endpointTypeModel.endpointTypeId
187
226
  }
188
227
  if (payload.currency && payload.currency !== currentOracleEndpoint.currency) {
228
+ step = 'getCurrencyById-7'
189
229
  const currencyModel = await currency.getCurrencyById(payload.currency)
190
230
  if (currencyModel) {
191
231
  newOracleEntry.currencyId = payload.currency
@@ -196,6 +236,7 @@ exports.updateOracle = async (params, payload) => {
196
236
  if (payload.isDefault && payload.isDefault !== currentOracleEndpoint.isDefault) {
197
237
  newOracleEntry.isDefault = payload.isDefault
198
238
  }
239
+ step = 'updateOracleEndpointById-8'
199
240
  await oracleEndpoint.updateOracleEndpointById(params.ID, newOracleEntry)
200
241
  histTimerEnd({ success: true })
201
242
  return true
@@ -205,7 +246,16 @@ exports.updateOracle = async (params, payload) => {
205
246
  } catch (err) {
206
247
  histTimerEnd({ success: false })
207
248
  Logger.isErrorEnabled && Logger.error(err)
208
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
249
+ const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
250
+ const extensions = err.extensions || []
251
+ const system = extensions.find((element) => element.key === 'system')?.value || ''
252
+ errorCounter.inc({
253
+ code: fspiopError?.apiErrorCode,
254
+ system,
255
+ operation: 'updateOracle',
256
+ step
257
+ })
258
+ throw fspiopError
209
259
  }
210
260
  }
211
261
 
@@ -222,6 +272,7 @@ exports.deleteOracle = async (params) => {
222
272
  'Delete Oracle',
223
273
  ['success']
224
274
  ).startTimer()
275
+ const errorCounter = Metrics.getCounter('errorCount')
225
276
  try {
226
277
  await oracleEndpoint.destroyOracleEndpointById(params.ID)
227
278
  histTimerEnd({ success: true })
@@ -229,6 +280,14 @@ exports.deleteOracle = async (params) => {
229
280
  } catch (err) {
230
281
  histTimerEnd({ success: false })
231
282
  Logger.isErrorEnabled && Logger.error(err)
232
- throw ErrorHandler.Factory.reformatFSPIOPError(err)
283
+ const fspiopError = ErrorHandler.Factory.reformatFSPIOPError(err)
284
+ const extensions = err.extensions || []
285
+ const system = extensions.find((element) => element.key === 'system')?.value || ''
286
+ errorCounter.inc({
287
+ code: fspiopError?.apiErrorCode,
288
+ system,
289
+ operation: 'deleteOracle'
290
+ })
291
+ throw fspiopError
233
292
  }
234
293
  }