@mojaloop/sdk-scheme-adapter 24.3.1 → 24.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/.ncurc.yaml +2 -1
  2. package/.yarn/cache/@babel-core-npm-7.26.10-0b29e369b5-0217325bd4.zip +0 -0
  3. package/.yarn/cache/@babel-generator-npm-7.26.10-ee5de9766f-b047378cb4.zip +0 -0
  4. package/.yarn/cache/@babel-helpers-npm-7.26.10-4eb1d94ec4-daa3689024.zip +0 -0
  5. package/.yarn/cache/@babel-parser-npm-7.26.10-51865d5633-81f9af962a.zip +0 -0
  6. package/.yarn/cache/@babel-traverse-npm-7.26.10-bdeb9ff2c2-9b58039cf3.zip +0 -0
  7. package/.yarn/cache/@babel-types-npm-7.26.10-1df6b33135-07340068ea.zip +0 -0
  8. package/.yarn/cache/@grpc-grpc-js-npm-1.13.0-8a179eeb73-5153924bd9.zip +0 -0
  9. package/.yarn/cache/{@mojaloop-api-snippets-npm-17.8.0-7566be28d1-ed10394e2d.zip → @mojaloop-api-snippets-npm-17.9.0-56be759f33-e21f71f413.zip} +0 -0
  10. package/.yarn/cache/@mojaloop-central-services-logger-npm-11.6.2-f23a495932-dbe46a02df.zip +0 -0
  11. package/.yarn/cache/@mojaloop-central-services-logger-npm-11.7.0-bd1e0d14fc-386d668607.zip +0 -0
  12. package/.yarn/cache/@mojaloop-central-services-metrics-npm-12.5.0-6977e34108-812240df40.zip +0 -0
  13. package/.yarn/cache/{@mojaloop-central-services-shared-npm-18.22.1-afa19f2925-27182cd5be.zip → @mojaloop-central-services-shared-npm-18.22.3-d3de464e63-09a0ab31b1.zip} +0 -0
  14. package/.yarn/cache/{@mojaloop-central-services-shared-npm-18.21.0-6755b8831a-d6c57dbf15.zip → @mojaloop-central-services-shared-npm-18.23.0-1dc7ef9c6e-5404b8b52b.zip} +0 -0
  15. package/.yarn/cache/{@mojaloop-event-sdk-npm-14.3.0-2aa8149477-6173c7d96f.zip → @mojaloop-event-sdk-npm-14.3.2-ff892a5f55-372ff7a256.zip} +0 -0
  16. package/.yarn/cache/@mojaloop-logging-bc-public-types-lib-npm-0.5.5-bedbbd6bc8-822bca428e.zip +0 -0
  17. package/.yarn/cache/{@mojaloop-ml-schema-transformer-lib-npm-2.5.6-c7788ac913-3556a96a40.zip → @mojaloop-ml-schema-transformer-lib-npm-2.5.8-ac5a2345a8-1d38e5c2ed.zip} +0 -0
  18. package/.yarn/cache/{@mojaloop-sdk-standard-components-npm-19.10.0-2948ef6f6d-000ddc4ae6.zip → @mojaloop-sdk-standard-components-npm-19.11.0-7029898826-da3795e27f.zip} +0 -0
  19. package/.yarn/cache/@rollup-rollup-linux-x64-musl-npm-4.35.0-4d96bf3a6f-8.zip +0 -0
  20. package/.yarn/install-state.gz +0 -0
  21. package/CHANGELOG.md +14 -0
  22. package/audit-ci.jsonc +2 -0
  23. package/modules/api-svc/package.json +9 -9
  24. package/modules/api-svc/src/InboundServer/handlers.js +30 -9
  25. package/modules/api-svc/src/OutboundServer/handlers.js +40 -1
  26. package/modules/api-svc/src/OutboundServer/index.js +0 -1
  27. package/modules/api-svc/src/lib/model/AccountsModel.js +73 -23
  28. package/modules/api-svc/test/unit/api/accounts/accounts.test.js +27 -1
  29. package/modules/api-svc/test/unit/api/accounts/data/deleteAccountSuccessResponse.json +16 -0
  30. package/modules/api-svc/test/unit/api/accounts/utils.js +45 -7
  31. package/modules/api-svc/test/unit/data/defaultConfig.json +1 -0
  32. package/modules/outbound-command-event-handler/package.json +3 -3
  33. package/modules/outbound-domain-event-handler/package.json +2 -2
  34. package/modules/private-shared-lib/package.json +3 -3
  35. package/package.json +2 -1
  36. package/.yarn/cache/@grpc-grpc-js-npm-1.12.6-a1a04f725c-eec210e689.zip +0 -0
  37. package/.yarn/cache/@hapi-hapi-npm-21.3.12-494107fd09-e833a84190.zip +0 -0
  38. package/.yarn/cache/@hapi-statehood-npm-8.1.1-b23eb2b02c-d371efa914.zip +0 -0
  39. package/.yarn/cache/@mojaloop-central-services-error-handling-npm-13.0.6-38733fdd51-26f32fda64.zip +0 -0
  40. package/.yarn/cache/@mojaloop-central-services-metrics-npm-12.4.5-95409a54bc-c4acfa9e84.zip +0 -0
  41. package/.yarn/cache/@mojaloop-central-services-shared-npm-18.18.2-8137f1eb81-a820a25d55.zip +0 -0
  42. package/.yarn/cache/@mojaloop-inter-scheme-proxy-cache-lib-npm-2.3.3-ca0069f863-f1f9e228ec.zip +0 -0
  43. package/.yarn/cache/@mojaloop-ml-schema-transformer-lib-npm-2.5.4-e84e9bcf4f-2ce61a546e.zip +0 -0
  44. package/.yarn/cache/@mojaloop-sdk-standard-components-npm-19.6.6-b23ec9b40c-016d0ea60e.zip +0 -0
  45. package/.yarn/cache/@mojaloop-sdk-standard-components-npm-19.7.1-41bada4515-6b413699ea.zip +0 -0
  46. package/.yarn/cache/@mojaloop-sdk-standard-components-npm-19.9.0-54f15be12d-042cb3fccc.zip +0 -0
  47. package/.yarn/cache/@rollup-rollup-linux-x64-musl-npm-4.34.8-ee9cc4ca11-8.zip +0 -0
  48. package/.yarn/cache/@rollup-rollup-linux-x64-musl-npm-4.34.9-ee6556627d-8.zip +0 -0
  49. package/.yarn/cache/axios-npm-1.7.9-3c98466f87-cb8ce29181.zip +0 -0
  50. package/.yarn/cache/axios-npm-1.8.1-8a5eaf948f-3c434b86bb.zip +0 -0
package/.ncurc.yaml CHANGED
@@ -10,5 +10,6 @@ reject: [
10
10
  ## TODO: The new version of nx causes submodules to be broken.
11
11
  "nx",
12
12
  ## esLint 9.15.0 caused the error: TypeError: Error while loading rule '@typescript-eslint/no-unused-expressions': Cannot read properties of undefined (reading 'allowShortCircuit')
13
- "eslint"
13
+ "eslint",
14
+ "@mojaloop/sdk-standard-components" # Need to use snapshot version for now until pending PR is merged
14
15
  ]
Binary file
package/CHANGELOG.md CHANGED
@@ -1,4 +1,18 @@
1
1
  # Changelog: [mojaloop/sdk-scheme-adapter](https://github.com/mojaloop/sdk-scheme-adapter)
2
+ ## [24.4.0](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.3.2...v24.4.0) (2025-03-19)
3
+
4
+
5
+ ### Features
6
+
7
+ * **csi-1244:** delete account endpoint ([#553](https://github.com/mojaloop/sdk-scheme-adapter/issues/553)) ([29efe6e](https://github.com/mojaloop/sdk-scheme-adapter/commit/29efe6eac8ec0b8664ef1e42e132976a6fdd5470))
8
+
9
+ ### [24.3.2](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.3.1...v24.3.2) (2025-03-10)
10
+
11
+
12
+ ### Chore
13
+
14
+ * fix axios high vulnerability ([#561](https://github.com/mojaloop/sdk-scheme-adapter/issues/561)) ([f118cc4](https://github.com/mojaloop/sdk-scheme-adapter/commit/f118cc48fda089e4f21fdd26a190eea0df1f5318))
15
+
2
16
  ### [24.3.1](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.3.0...v24.3.1) (2025-03-10)
3
17
 
4
18
 
package/audit-ci.jsonc CHANGED
@@ -4,5 +4,7 @@
4
4
  // Only use one of ["low": true, "moderate": true, "high": true, "critical": true]
5
5
  "moderate": true,
6
6
  "allowlist": [
7
+ "GHSA-968p-4wvh-cqc8", // https://github.com/advisories/GHSA-968p-4wvh-cqc8
8
+ "GHSA-jr5f-v2jv-69x6" // https://github.com/advisories/GHSA-jr5f-v2jv-69x6
7
9
  ]
8
10
  }
@@ -64,18 +64,18 @@
64
64
  },
65
65
  "dependencies": {
66
66
  "@koa/cors": "5.0.0",
67
- "@mojaloop/api-snippets": "17.8.0",
67
+ "@mojaloop/api-snippets": "17.9.0",
68
68
  "@mojaloop/central-services-error-handling": "13.0.7",
69
- "@mojaloop/central-services-logger": "11.5.5",
70
- "@mojaloop/central-services-metrics": "12.4.5",
71
- "@mojaloop/central-services-shared": "18.22.1",
72
- "@mojaloop/event-sdk": "14.3.0",
69
+ "@mojaloop/central-services-logger": "11.7.0",
70
+ "@mojaloop/central-services-metrics": "12.5.0",
71
+ "@mojaloop/central-services-shared": "18.23.0",
72
+ "@mojaloop/event-sdk": "14.3.2",
73
73
  "@mojaloop/logging-bc-client-lib": "0.5.8",
74
- "@mojaloop/ml-schema-transformer-lib": "2.5.6",
74
+ "@mojaloop/ml-schema-transformer-lib": "2.5.8",
75
75
  "@mojaloop/sdk-scheme-adapter-private-shared-lib": "workspace:^",
76
- "@mojaloop/sdk-standard-components": "19.10.0",
76
+ "@mojaloop/sdk-standard-components": "19.11.0",
77
77
  "ajv": "8.17.1",
78
- "axios": "1.8.2",
78
+ "axios": "1.8.3",
79
79
  "body-parser": "1.20.3",
80
80
  "co-body": "6.2.0",
81
81
  "dotenv": "16.4.7",
@@ -100,7 +100,7 @@
100
100
  "ws": "8.18.1"
101
101
  },
102
102
  "devDependencies": {
103
- "@babel/core": "7.26.9",
103
+ "@babel/core": "7.26.10",
104
104
  "@babel/preset-env": "7.26.9",
105
105
  "@redocly/openapi-cli": "1.0.0-beta.95",
106
106
  "@types/jest": "29.5.14",
@@ -409,10 +409,18 @@ const putParticipantsByTypeAndId = async (ctx) => {
409
409
  };
410
410
 
411
411
  // publish an event onto the cache for subscribers to action
412
- const cacheId = `${idType}_${idValue}` + (idSubValue ? `_${idSubValue}` : '');
413
- await ctx.state.cache.publish(cacheId, {
414
- data
415
- });
412
+ let cacheId = `${idType}_${idValue}` + (idSubValue ? `_${idSubValue}` : '');
413
+ const message = { data };
414
+
415
+ // We need to determine if this callback is a response to either a GET/POST /participants
416
+ // or DELETE /participants/{Type}/{ID}/{SubId} request
417
+ const adCacheId = `ad_${cacheId}`;
418
+ if (ctx.state.cache._callbacks[adCacheId]) {
419
+ cacheId = adCacheId;
420
+ message.type = 'accountDeletionSuccessfulResponse';
421
+ }
422
+
423
+ await ctx.state.cache.publish(cacheId, message);
416
424
  ctx.response.status = ReturnCodes.OK.CODE;
417
425
  } else {
418
426
  // SDK does not make participants requests so we should not expect any calls to this method
@@ -423,7 +431,9 @@ const putParticipantsByTypeAndId = async (ctx) => {
423
431
 
424
432
 
425
433
  /**
426
- * Handles a PUT /participants/{Type}/{ID}/{SubId}/error request. This is an error response to a GET /participants/{Type}/{ID}/{SubId} request
434
+ * Handles a PUT /participants/{Type}/{ID}/{SubId}/error request.
435
+ * This is an error response to a GET /participants/{Type}/{ID}/{SubId} or
436
+ * DELETE /participants/{Type}/{ID}/{SubId} request
427
437
  */
428
438
  const putParticipantsByTypeAndIdError = async(ctx) => {
429
439
  const idType = ctx.state.path.params.Type;
@@ -437,10 +447,18 @@ const putParticipantsByTypeAndIdError = async(ctx) => {
437
447
  // note that we publish the event the same way we publish a success PUT
438
448
  // the subscriber will notice the body contains an errorInformation property
439
449
  // and recognise it as an error response
440
- const cacheId = `${idType}_${idValue}` + (idSubValue ? `_${idSubValue}` : '');
441
- await ctx.state.cache.publish(cacheId, {
442
- data
443
- });
450
+ let cacheId = `${idType}_${idValue}` + (idSubValue ? `_${idSubValue}` : '');
451
+ const message = { data };
452
+
453
+ // We need to determine if this callback is a response to either a GET/POST /participants
454
+ // or DELETE /participants/{Type}/{ID}/{SubId} request
455
+ const adCacheId = `ad_${cacheId}`;
456
+ if (ctx.state.cache._callbacks[adCacheId]) {
457
+ cacheId = adCacheId;
458
+ message.type = 'accountDeletionErrorResponse';
459
+ }
460
+
461
+ await ctx.state.cache.publish(cacheId, message);
444
462
 
445
463
  ctx.response.status = ReturnCodes.OK.CODE;
446
464
  ctx.response.body = '';
@@ -1122,6 +1140,9 @@ module.exports = {
1122
1140
  put: putParticipantsByTypeAndId,
1123
1141
  get: getParticipantsByTypeAndId
1124
1142
  },
1143
+ '/participants/{Type}/{ID}/error': {
1144
+ put: putParticipantsByTypeAndIdError
1145
+ },
1125
1146
  '/participants/{Type}/{ID}/{SubId}': {
1126
1147
  put: putParticipantsByTypeAndId,
1127
1148
  get: getParticipantsByTypeAndId
@@ -485,6 +485,39 @@ const postAccounts = async (ctx) => {
485
485
  }
486
486
  };
487
487
 
488
+ /**
489
+ * Handler for outbound accounts deletion request
490
+ */
491
+ const deleteAccountByTypeAndId = async (ctx) => {
492
+ try {
493
+ const model = new AccountsModel({
494
+ ...ctx.state.conf,
495
+ ...ctx.state.path?.params?.dfspId && {dfspId: ctx.state.path.params.dfspId},
496
+ cache: ctx.state.cache,
497
+ logger: ctx.state.logger,
498
+ wso2: ctx.state.wso2,
499
+ });
500
+
501
+ const args = {
502
+ currentState: 'deleteAccount',
503
+ idType: ctx.state.path.params.Type,
504
+ idValue: ctx.state.path.params.ID,
505
+ subIdOrType: ctx.state.path.params.SubId,
506
+ };
507
+
508
+ // initialize the accounts model and run it
509
+ await model.initialize(args);
510
+ const response = await model.run();
511
+
512
+ // return the result
513
+ ctx.response.status = ReturnCodes.OK.CODE;
514
+ ctx.response.body = response;
515
+ }
516
+ catch(err) {
517
+ return handleAccountsError('deleteAccountByTypeAndId', err, ctx);
518
+ }
519
+ };
520
+
488
521
  const postRequestToPay = async (ctx) => {
489
522
  try {
490
523
  // this requires a multi-stage sequence with the switch.
@@ -683,7 +716,13 @@ module.exports = {
683
716
  get: getBulkQuoteById,
684
717
  },
685
718
  '/accounts': {
686
- post: postAccounts
719
+ post: postAccounts,
720
+ },
721
+ '/accounts/{Type}/{ID}': {
722
+ delete: deleteAccountByTypeAndId,
723
+ },
724
+ '/accounts/{Type}/{ID}/{SubId}': {
725
+ delete: deleteAccountByTypeAndId,
687
726
  },
688
727
  '/requestToPay': {
689
728
  post: postRequestToPay
@@ -92,7 +92,6 @@ class OutboundApi extends EventEmitter {
92
92
 
93
93
  this._api.use(middlewares.createRequestValidator(validator));
94
94
  this._api.use(router(handlers, conf));
95
-
96
95
  this._api.use(middlewares.createResponseLogging(this._logger));
97
96
  }
98
97
 
@@ -74,6 +74,7 @@ class AccountsModel {
74
74
  init: initState,
75
75
  transitions: [
76
76
  { name: 'createAccounts', from: 'start', to: 'succeeded' },
77
+ { name: 'deleteAccount', to: 'succeeded' },
77
78
  { name: 'error', from: '*', to: 'errored' },
78
79
  ],
79
80
  methods: {
@@ -140,6 +141,9 @@ class AccountsModel {
140
141
  case 'createAccounts':
141
142
  return this._createAccounts();
142
143
 
144
+ case 'deleteAccount':
145
+ return this._deleteAccount();
146
+
143
147
  case 'error':
144
148
  this._logger.isErrorEnabled && this._logger.error(`State machine is erroring with error: ${safeStringify(args)}`);
145
149
  this._data.lastError = args[0] || new BackendError('unspecified error', 500);
@@ -150,25 +154,64 @@ class AccountsModel {
150
154
  }
151
155
  }
152
156
 
157
+ async _createAccounts() {
158
+ const requests = this._buildRequests();
159
+ for await (let request of requests) {
160
+ const response = await this._executeAccountsRequest(request, 'createAccounts');
161
+ this._data.response.push(...this._buildClientResponse(response));
162
+ }
163
+ }
164
+
165
+ async _deleteAccount() {
166
+ const request = {
167
+ requestId: this._idGenerator(),
168
+ idType: this._data.idType,
169
+ idValue: this._data.idValue,
170
+ ...this._data.subIdOrType && { idSubValue: this._data.subIdOrType },
171
+ };
172
+ const response = await this._executeAccountsRequest(request, 'deleteAccount');
173
+ this._data.response.push(...this._buildClientResponse(response, 'deleteAccount'));
174
+ }
153
175
 
154
- async _executeCreateAccountsRequest(request) {
176
+ async _executeAccountsRequest(request, requestType='createAccounts') {
155
177
  const accountRequest = request;
178
+ const processesData = {
179
+ createAccounts: {
180
+ actionName: 'Account creation',
181
+ actionText: 'creating accounts',
182
+ responseProp: 'postAccountsResponse',
183
+ errorType: 'accountsCreationErrorResponse',
184
+ successType: 'accountsCreationSuccessfulResponse',
185
+ makeCacheKey: (req) => `ac_${req.requestId}`,
186
+ sendRequest: this._requests.postParticipants.bind(this._requests)
187
+ },
188
+ deleteAccount: {
189
+ actionName: 'Account deletion',
190
+ actionText: 'deleting account',
191
+ responseProp: 'deleteAccountResponse',
192
+ errorType: 'accountDeletionErrorResponse',
193
+ successType: 'accountDeletionSuccessfulResponse',
194
+ makeCacheKey: (req) => `ad_${req.idType}_${req.idValue}` + (req.idSubValue ? `_${req.idSubValue}` : ''),
195
+ sendRequest: (req) => this._requests.deleteParticipants(req.idType, req.idValue, req.idSubValue)
196
+ }
197
+ };
156
198
 
157
199
  // eslint-disable-next-line no-async-promise-executor
158
200
  return new Promise(async (resolve, reject) => {
159
- const requestKey = `ac_${accountRequest.requestId}`;
201
+ const { actionName, responseProp, actionText, errorType, successType, makeCacheKey, sendRequest } = processesData[requestType];
202
+ const requestKey = makeCacheKey(accountRequest);
160
203
 
161
204
  const subId = await this._cache.subscribe(requestKey, async (cn, msg, subId) => {
162
205
  try {
163
206
  let error;
164
207
  const message = JSON.parse(msg);
165
- this._data.postAccountsResponse = message.data;
208
+ this._data[responseProp] = message.data;
166
209
 
167
- if (message.type === 'accountsCreationErrorResponse') {
168
- error = new BackendError(`Got an error response creating accounts: ${safeStringify(this._data.postAccountsResponse.body)}`, 500);
169
- error.mojaloopError = this._data.postAccountsResponse.body;
170
- } else if (message.type !== 'accountsCreationSuccessfulResponse') {
171
- this._logger.push(safeStringify(this._data.postAccountsResponse)).debug(
210
+ if (message.type === errorType) {
211
+ error = new BackendError(`Got an error response ${actionText}: ${safeStringify(this._data[responseProp].body)}`, 500);
212
+ error.mojaloopError = this._data[responseProp].body;
213
+ } else if (message.type !== successType) {
214
+ this._logger.push(safeStringify(this._data[responseProp])).debug(
172
215
  `Ignoring cache notification for request ${requestKey}. ` +
173
216
  `Unknown message type ${message.type}.`
174
217
  );
@@ -189,8 +232,8 @@ class AccountsModel {
189
232
  return reject(error);
190
233
  }
191
234
 
192
- const response = this._data.postAccountsResponse;
193
- this._logger.isDebugEnabled && this._logger.push({ response }).debug('Account creation response received');
235
+ const response = this._data[responseProp];
236
+ this._logger.isDebugEnabled && this._logger.push({ response }).debug(`${actionName} response received`);
194
237
  return resolve(response);
195
238
  }
196
239
  catch(err) {
@@ -200,7 +243,7 @@ class AccountsModel {
200
243
 
201
244
  // set up a timeout for the request
202
245
  const timeout = setTimeout(() => {
203
- const err = new BackendError(`Timeout waiting for response to account creation request ${accountRequest.requestId}`, 504);
246
+ const err = new BackendError(`Timeout waiting for response to ${actionName.toLowerCase()} request ${accountRequest.requestId}`, 504);
204
247
 
205
248
  // we dont really care if the unsubscribe fails but we should log it regardless
206
249
  this._cache.unsubscribe(requestKey, subId).catch(e => {
@@ -210,11 +253,9 @@ class AccountsModel {
210
253
  return reject(err);
211
254
  }, this._requestProcessingTimeoutSeconds * 1000);
212
255
 
213
- // now we have a timeout handler and a cache subscriber hooked up we can fire off
214
- // a POST /participants request to the switch
215
256
  try {
216
- const res = await this._requests.postParticipants(accountRequest);
217
- this._logger.isDebugEnabled && this._logger.push({ res }).debug('Account creation request sent to peer');
257
+ const res = await sendRequest(accountRequest);
258
+ this._logger.isDebugEnabled && this._logger.push({ res }).debug(`${actionName} request sent to peer`);
218
259
  }
219
260
  catch(err) {
220
261
  // cancel the timout and unsubscribe before rejecting the promise
@@ -230,16 +271,20 @@ class AccountsModel {
230
271
  });
231
272
  }
232
273
 
233
-
234
- async _createAccounts() {
235
- const requests = this._buildRequests();
236
- for await (let request of requests) {
237
- const response = await this._executeCreateAccountsRequest(request);
238
- this._data.response.push(...this._buildClientResponse(response));
274
+ _buildClientResponse(response, responseType='createAccounts') {
275
+ if (responseType == 'deleteAccount') {
276
+ if (response.body.errorInformation) {
277
+ return [{
278
+ error: {
279
+ statusCode: response.body.errorInformation.errorCode,
280
+ message: response.body.errorInformation.errorDescription,
281
+ },
282
+ }];
283
+ } else {
284
+ return [{ ...response.body }];
285
+ }
239
286
  }
240
- }
241
287
 
242
- _buildClientResponse(response) {
243
288
  return response.body.partyList.map(party => ({
244
289
  idType: party.partyId.partyIdType,
245
290
  idValue: party.partyId.partyIdentifier,
@@ -377,6 +422,11 @@ class AccountsModel {
377
422
  break;
378
423
  }
379
424
 
425
+ case 'deleteAccount':
426
+ await this._stateMachine.deleteAccount();
427
+
428
+ break;
429
+
380
430
  case 'succeeded':
381
431
  // all steps complete so return
382
432
  this._logger.isDebugEnabled && this._logger.debug('Accounts creation completed');
@@ -41,7 +41,7 @@ jest.mock('redis');
41
41
  const redis = require('redis');
42
42
  const uuid = require('@mojaloop/central-services-shared').Util.id;
43
43
  const {createValidators, createTestServers, destroyTestServers} = require('../utils');
44
- const {createPostAccountsTester} = require('./utils');
44
+ const {createPostAccountsTester, createDeleteAccountTester} = require('./utils');
45
45
 
46
46
  const defaultConfig = require('../../data/defaultConfig');
47
47
 
@@ -51,9 +51,11 @@ const postAccountsSuccessResponseWithError1 = require('./data/postAccountsSucces
51
51
  const postAccountsSuccessResponseWithError2 = require('./data/postAccountsSuccessResponseWithError2');
52
52
  const postAccountsErrorTimeoutResponse = require('./data/postAccountsErrorTimeoutResponse');
53
53
  const postAccountsErrorMojaloopResponse = require('./data/postAccountsErrorMojaloopResponse');
54
+ const deleteAccountSuccessResponse = require('./data/deleteAccountSuccessResponse');
54
55
 
55
56
  describe('Outbound Accounts API', () => {
56
57
  let testPostAccounts;
58
+ let testDeleteAccount;
57
59
  let validatorsInfo;
58
60
  let serversInfo;
59
61
  let redisClient;
@@ -149,4 +151,28 @@ describe('Outbound Accounts API', () => {
149
151
  postAccountsErrorMojaloopResponse);
150
152
  });
151
153
  });
154
+
155
+ describe('DELETE /accounts/{Type}/{ID}/{SubId}', () => {
156
+ const reqParams = {
157
+ Type: 'MSISDN',
158
+ ID: '123456789'
159
+ }
160
+ beforeEach(() => {
161
+ uuid.__reset();
162
+ redisClient.flushdb();
163
+ testDeleteAccount = createDeleteAccountTester({
164
+ reqInbound: serversInfo.reqInbound,
165
+ reqOutbound: serversInfo.reqOutbound,
166
+ reqParams,
167
+ apiSpecsOutbound: validatorsInfo.apiSpecsOutbound,
168
+ });
169
+ });
170
+
171
+ test('should return success response', () => {
172
+ const putBodyFn = (body) => ({
173
+ fspId: 'mojaloop-sdk',
174
+ });
175
+ return testDeleteAccount(putBodyFn, 200, deleteAccountSuccessResponse);
176
+ });
177
+ });
152
178
  });
@@ -0,0 +1,16 @@
1
+ {
2
+ "idType": "MSISDN",
3
+ "idValue": "123456789",
4
+ "currentState": "COMPLETED",
5
+ "modelId": "00000000000000000000000001",
6
+ "deleteAccountResponse": {
7
+ "body": {
8
+ "fspId": "mojaloop-sdk"
9
+ }
10
+ },
11
+ "response": [
12
+ {
13
+ "fspId": "mojaloop-sdk"
14
+ }
15
+ ]
16
+ }
@@ -10,7 +10,7 @@ const postAccountsBody = require('./data/postAccountsBody');
10
10
  * @param apiSpecsOutbound
11
11
  * @returns Function(putBodyFn:function, responseCode:number, responseBody:object) => Promise
12
12
  */
13
- function createPostAccountsTester({ reqInbound, reqOutbound, apiSpecsOutbound }) {
13
+ function createPostAccountsTester({ reqInbound, reqOutbound, apiSpecsOutbound, reqParams = {} }, requestType=undefined) {
14
14
  /**
15
15
  *
16
16
  * @param putBodyFn {function}
@@ -38,13 +38,39 @@ function createPostAccountsTester({ reqInbound, reqOutbound, apiSpecsOutbound })
38
38
  .expect(200);
39
39
  };
40
40
 
41
+ const sendPutParticipantsForDelete = async (requestBody) => {
42
+ const body = JSON.parse(requestBody);
43
+ const putBody = await Promise.resolve(putBodyFn(body));
44
+ let putUrl = `/participants/${reqParams.Type}/${reqParams.ID}`;
45
+ if (putBody.errorInformation) {
46
+ putUrl += '/error';
47
+ }
48
+
49
+ return reqInbound.put(putUrl)
50
+ .send(putBody)
51
+ .set('Date', new Date().toISOString())
52
+ .set('content-type', 'application/vnd.interoperability.participants+json;version=1.1')
53
+ .set('fspiop-source', 'mojaloop-sdk')
54
+ .expect(200);
55
+ };
56
+
41
57
  mockAxios.reset();
42
- mockAxios.onPost('/participants').reply((reqConfig) => {
43
- pendingRequest = sendPutParticipants(reqConfig.data);
44
- return [202, null, jsonContentTypeHeader];
45
- });
46
58
 
47
- const res = await reqOutbound.post('/accounts').send(postAccountsBody);
59
+ if (requestType === 'deleteAccount') {
60
+ mockAxios.onDelete(`/participants/${reqParams.Type}/${reqParams.ID}`).reply((reqConfig) => {
61
+ pendingRequest = sendPutParticipantsForDelete('{ "fspId": "mojaloop-sdk" }');
62
+ return [202, null, jsonContentTypeHeader];
63
+ });
64
+ } else {
65
+ mockAxios.onPost('/participants').reply((reqConfig) => {
66
+ pendingRequest = sendPutParticipants(reqConfig.data);
67
+ return [202, null, jsonContentTypeHeader];
68
+ });
69
+ }
70
+
71
+ let res = requestType === 'deleteAccount'
72
+ ? await reqOutbound.delete(`/accounts/${reqParams.Type}/${reqParams.ID}`)
73
+ : await reqOutbound.post('/accounts').send(postAccountsBody);
48
74
  const {body} = res;
49
75
  expect(res.statusCode).toEqual(responseCode);
50
76
 
@@ -61,8 +87,15 @@ function createPostAccountsTester({ reqInbound, reqOutbound, apiSpecsOutbound })
61
87
  delete body.postAccountsResponse.headers;
62
88
  }
63
89
 
90
+ if(body.deleteAccountResponse) {
91
+ delete body.deleteAccountResponse.headers;
92
+ }
93
+
64
94
  expect(body).toEqual(responseBody);
65
- const responseValidator = new OpenAPIResponseValidator(apiSpecsOutbound.paths['/accounts'].post);
95
+
96
+ const responseValidator = requestType === 'deleteAccount'
97
+ ? new OpenAPIResponseValidator(apiSpecsOutbound.paths['/accounts/{Type}/{ID}'].delete)
98
+ : new OpenAPIResponseValidator(apiSpecsOutbound.paths['/accounts'].post);
66
99
  const err = responseValidator.validateResponse(responseCode, body);
67
100
  if (err) {
68
101
  throw err;
@@ -71,6 +104,11 @@ function createPostAccountsTester({ reqInbound, reqOutbound, apiSpecsOutbound })
71
104
  };
72
105
  }
73
106
 
107
+ const createDeleteAccountTester = ({ reqInbound, reqOutbound, reqParams, apiSpecsOutbound }) => {
108
+ return createPostAccountsTester({ reqInbound, reqOutbound, reqParams, apiSpecsOutbound }, 'deleteAccount');
109
+ }
110
+
74
111
  module.exports = {
75
112
  createPostAccountsTester,
113
+ createDeleteAccountTester,
76
114
  };
@@ -40,6 +40,7 @@
40
40
  "requestProcessingTimeoutSeconds": 30,
41
41
  "autoAcceptQuotes": true,
42
42
  "autoAcceptParty": true,
43
+ "autoAcceptParticipantsPut": true,
43
44
  "useQuoteSourceFSPAsTransferPayeeFSP": false,
44
45
  "tls": {
45
46
  },
@@ -41,10 +41,10 @@
41
41
  "snapshot": "standard-version --no-verify --skip.changelog --prerelease snapshot --releaseCommitMessageFormat 'chore(snapshot): {{currentTag}}'"
42
42
  },
43
43
  "dependencies": {
44
- "@mojaloop/api-snippets": "17.8.0",
45
- "@mojaloop/central-services-shared": "18.22.1",
44
+ "@mojaloop/api-snippets": "17.9.0",
45
+ "@mojaloop/central-services-shared": "18.23.0",
46
46
  "@mojaloop/logging-bc-client-lib": "0.5.8",
47
- "@mojaloop/logging-bc-public-types-lib": "0.5.4",
47
+ "@mojaloop/logging-bc-public-types-lib": "0.5.5",
48
48
  "@mojaloop/sdk-scheme-adapter-private-shared-lib": "workspace:^",
49
49
  "ajv": "8.17.1",
50
50
  "convict": "6.2.4",
@@ -41,9 +41,9 @@
41
41
  "snapshot": "standard-version --no-verify --skip.changelog --prerelease snapshot --releaseCommitMessageFormat 'chore(snapshot): {{currentTag}}'"
42
42
  },
43
43
  "dependencies": {
44
- "@mojaloop/api-snippets": "17.8.0",
44
+ "@mojaloop/api-snippets": "17.9.0",
45
45
  "@mojaloop/logging-bc-client-lib": "0.5.8",
46
- "@mojaloop/logging-bc-public-types-lib": "0.5.4",
46
+ "@mojaloop/logging-bc-public-types-lib": "0.5.5",
47
47
  "@mojaloop/sdk-scheme-adapter-private-shared-lib": "workspace:^",
48
48
  "convict": "6.2.4",
49
49
  "express": "4.21.2",
@@ -29,9 +29,9 @@
29
29
  "snapshot": "standard-version --no-verify --skip.changelog --prerelease snapshot --releaseCommitMessageFormat 'chore(snapshot): {{currentTag}}'"
30
30
  },
31
31
  "dependencies": {
32
- "@mojaloop/api-snippets": "17.8.0",
33
- "@mojaloop/central-services-shared": "18.22.1",
34
- "@mojaloop/logging-bc-public-types-lib": "0.5.4",
32
+ "@mojaloop/api-snippets": "17.9.0",
33
+ "@mojaloop/central-services-shared": "18.23.0",
34
+ "@mojaloop/logging-bc-public-types-lib": "0.5.5",
35
35
  "@mojaloop/platform-shared-lib-messaging-types-lib": "0.7.1",
36
36
  "@mojaloop/platform-shared-lib-nodejs-kafka-client-lib": "0.5.18",
37
37
  "ajv": "8.17.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter",
3
- "version": "24.3.1",
3
+ "version": "24.4.0",
4
4
  "description": "mojaloop sdk-scheme-adapter",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mojaloop/sdk-scheme-adapter",
@@ -114,6 +114,7 @@
114
114
  "yargs-parser": "21.1.1"
115
115
  },
116
116
  "resolutions": {
117
+ "axios": "1.8.2",
117
118
  "body-parser": "1.20.3",
118
119
  "cacache/tar": "6.2.1",
119
120
  "path-to-regexp": "0.1.12",