quoting-service 17.13.6 → 17.13.7

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/.grype.yaml CHANGED
@@ -5,6 +5,7 @@ ignore:
5
5
  - vulnerability: CVE-2025-9230
6
6
  - vulnerability: CVE-2025-9232
7
7
  - vulnerability: CVE-2025-9231
8
+ - vulnerability: GHSA-9965-vmph-33xx
8
9
 
9
10
  # Set output format defaults
10
11
  output:
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [17.13.7](https://github.com/mojaloop/quoting-service/compare/v17.13.6...v17.13.7) (2025-10-31)
6
+
7
+
8
+ ### Chore
9
+
10
+ * **sbom:** update sbom [skip ci] ([60ff730](https://github.com/mojaloop/quoting-service/commit/60ff7300a80985b763a2b7a7678887e269aa4ac9))
11
+
12
+
13
+ ### Refactors
14
+
15
+ * update requests with http timeout ([#436](https://github.com/mojaloop/quoting-service/issues/436)) ([8d3efee](https://github.com/mojaloop/quoting-service/commit/8d3efee4e119545d814fc975a2982e012a56cd65))
16
+
5
17
  ### [17.13.6](https://github.com/mojaloop/quoting-service/compare/v17.13.5...v17.13.6) (2025-10-06)
6
18
 
7
19
 
package/audit-ci.jsonc CHANGED
@@ -4,5 +4,6 @@
4
4
  // Only use one of ["low": true, "moderate": true, "high": true, "critical": true]
5
5
  "moderate": true,
6
6
  "allowlist": [
7
+ "GHSA-9965-vmph-33xx"
7
8
  ]
8
9
  }
@@ -12,6 +12,7 @@
12
12
  "PRECISION": 18,
13
13
  "SCALE": 4
14
14
  },
15
+ "HTTP_REQUEST_TIMEOUT_MS": 20000,
15
16
  "PROTOCOL_VERSIONS": {
16
17
  "CONTENT": {
17
18
  "DEFAULT": "2.0",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "quoting-service",
3
3
  "description": "Quoting Service hosted by a scheme",
4
4
  "license": "Apache-2.0",
5
- "version": "17.13.6",
5
+ "version": "17.13.7",
6
6
  "author": "ModusBox",
7
7
  "contributors": [
8
8
  "Georgi Georgiev <georgi.georgiev@modusbox.com>",
@@ -116,18 +116,18 @@
116
116
  "@mojaloop/central-services-health": "15.2.0",
117
117
  "@mojaloop/central-services-logger": "11.10.1",
118
118
  "@mojaloop/central-services-metrics": "12.8.0",
119
- "@mojaloop/central-services-shared": "18.34.1",
120
- "@mojaloop/central-services-stream": "11.8.8",
121
- "@mojaloop/event-sdk": "14.8.0",
119
+ "@mojaloop/central-services-shared": "18.34.3",
120
+ "@mojaloop/central-services-stream": "11.8.10",
121
+ "@mojaloop/event-sdk": "14.8.1",
122
122
  "@mojaloop/inter-scheme-proxy-cache-lib": "2.9.0",
123
123
  "@mojaloop/ml-number": "11.4.0",
124
124
  "@mojaloop/ml-schema-transformer-lib": "2.7.8",
125
125
  "@mojaloop/sdk-standard-components": "19.18.0",
126
126
  "ajv": "8.17.1",
127
127
  "ajv-keywords": "5.1.0",
128
- "axios": "1.12.2",
128
+ "axios": "1.13.1",
129
129
  "blipp": "4.0.2",
130
- "commander": "14.0.1",
130
+ "commander": "14.0.2",
131
131
  "event-stream": "4.0.1",
132
132
  "fast-safe-stringify": "2.1.1",
133
133
  "joi": "18.0.1",
@@ -135,7 +135,7 @@
135
135
  "knex": "3.1.0",
136
136
  "memory-cache": "0.2.0",
137
137
  "minimist": "1.2.8",
138
- "mysql2": "^3.15.1",
138
+ "mysql2": "^3.15.3",
139
139
  "node-fetch": "3.3.2",
140
140
  "parse-strings-in-object": "2.0.0",
141
141
  "rc": "1.2.8"
@@ -145,10 +145,10 @@
145
145
  "eslint": "8.57.1",
146
146
  "eslint-config-standard": "17.1.0",
147
147
  "eslint-plugin-jest": "29.0.1",
148
- "ioredis-mock": "8.13.0",
148
+ "ioredis-mock": "8.13.1",
149
149
  "jest": "29.7.0",
150
150
  "jest-junit": "16.0.0",
151
- "npm-check-updates": "19.0.0",
151
+ "npm-check-updates": "19.1.2",
152
152
  "nyc": "17.1.0",
153
153
  "pre-commit": "1.2.2",
154
154
  "replace": "1.2.2",
package/src/lib/config.js CHANGED
@@ -165,6 +165,7 @@ class Config {
165
165
  this.payloadCache = RC.PAYLOAD_CACHE
166
166
  this.originalPayloadStorage = RC.ORIGINAL_PAYLOAD_STORAGE || PAYLOAD_STORAGES.none
167
167
  this.simpleAudit = RC.SIMPLE_AUDIT || false
168
+ this.httpRequestTimeoutMs = RC.HTTP_REQUEST_TIMEOUT_MS || 20000
168
169
  }
169
170
  }
170
171
 
package/src/lib/http.js CHANGED
@@ -42,10 +42,12 @@ const ErrorHandler = require('@mojaloop/central-services-error-handling')
42
42
 
43
43
  const { logger } = require('../lib')
44
44
  const { getStackOrInspect } = require('../lib/util')
45
+ const Config = require('./config')
45
46
 
46
47
  axios.defaults.httpAgent = new http.Agent({ keepAlive: true })
47
48
  axios.defaults.httpAgent.toJSON = () => ({})
48
49
  axios.defaults.headers.common = {}
50
+ const config = new Config()
49
51
 
50
52
  /**
51
53
  * Encapsulates making an HTTP request and translating any error response into a domain-specific
@@ -56,15 +58,12 @@ axios.defaults.headers.common = {}
56
58
  * @returns {Promise<void>}
57
59
  */
58
60
  async function httpRequest (opts, fspiopSource) {
59
- // Network errors lob an exception. Bear in mind 3xx 4xx and 5xx are not network errors so we
60
- // need to wrap the request below in a `try catch` to handle network errors
61
- let res
62
- let body
63
61
  const log = logger.child({ component: 'httpRequest', fspiopSource })
64
62
  log.debug('httpRequest is started...')
65
-
63
+ let res
64
+ let body
66
65
  try {
67
- res = await axios.request(opts)
66
+ res = await httpRequestBase(opts)
68
67
  body = await res.data
69
68
  log.verbose('httpRequest is finished', { body, opts })
70
69
  } catch (e) {
@@ -77,7 +76,6 @@ async function httpRequest (opts, fspiopSource) {
77
76
  fspiopSource)
78
77
  }
79
78
 
80
- // handle non network related errors below
81
79
  if (res.status < 200 || res.status >= 300) {
82
80
  const errObj = {
83
81
  opts,
@@ -96,6 +94,14 @@ async function httpRequest (opts, fspiopSource) {
96
94
  return body
97
95
  }
98
96
 
97
+ async function httpRequestBase (opts, axiosInstance = axios) {
98
+ return axiosInstance.request({
99
+ timeout: config.httpRequestTimeoutMs,
100
+ ...opts
101
+ })
102
+ }
103
+
99
104
  module.exports = {
100
- httpRequest
105
+ httpRequest,
106
+ httpRequestBase
101
107
  }
package/src/lib/util.js CHANGED
@@ -37,7 +37,6 @@
37
37
  const crypto = require('node:crypto')
38
38
  const path = require('node:path')
39
39
  const util = require('node:util')
40
- const axios = require('axios')
41
40
  const ErrorHandler = require('@mojaloop/central-services-error-handling')
42
41
  const { Enum, Util } = require('@mojaloop/central-services-shared')
43
42
  const { AuditEventAction } = require('@mojaloop/event-sdk')
@@ -47,6 +46,7 @@ const { logger } = require('../lib')
47
46
  const Config = require('./config')
48
47
 
49
48
  const rethrow = require('@mojaloop/central-services-shared').Util.rethrow.with('QS')
49
+ const { httpRequestBase } = require('./http')
50
50
  const config = new Config()
51
51
 
52
52
  const failActionHandler = async (request, h, err) => {
@@ -295,8 +295,8 @@ const fetchParticipantInfo = async (source, destination, cache, proxyClient) =>
295
295
 
296
296
  const cacheParticipantData = async (dfspId, config, cache) => {
297
297
  const url = `${config.switchEndpoint}/participants/${dfspId}`
298
- const { data } = await axios.request({ url })
299
- const participantData = { data }
298
+ const res = await httpRequestBase({ url })
299
+ const participantData = { data: res.data }
300
300
  cache && cache.put(`fetchParticipantInfo_${dfspId}`, participantData, config.participantDataCacheExpiresInMs)
301
301
  return participantData
302
302
  }
@@ -40,6 +40,7 @@ const EventSdk = require('@mojaloop/event-sdk')
40
40
 
41
41
  const LOCAL_ENUM = require('../lib/enum')
42
42
  const BaseQuotesModel = require('./BaseQuotesModel')
43
+ const { httpRequestBase } = require('../lib/http')
43
44
 
44
45
  const reformatFSPIOPError = ErrorHandler.Factory.reformatFSPIOPError
45
46
 
@@ -420,7 +421,7 @@ class BulkQuotesModel extends BaseQuotesModel {
420
421
  super.addFspiopSignatureHeader(opts)
421
422
 
422
423
  step = 'axios-request-2'
423
- res = await axios.request(opts)
424
+ res = await httpRequestBase(opts, axios)
424
425
  } catch (err) {
425
426
  log.warn('error in axios.request:', err)
426
427
  const extensions = err.extensions || []
@@ -39,6 +39,7 @@ const dto = require('../lib/dto')
39
39
 
40
40
  const { RESOURCES, ERROR_MESSAGES } = require('../constants')
41
41
  const BaseQuotesModel = require('./BaseQuotesModel')
42
+ const { httpRequestBase } = require('../lib/http')
42
43
 
43
44
  const reformatFSPIOPError = ErrorHandler.Factory.reformatFSPIOPError
44
45
 
@@ -804,7 +805,7 @@ class FxQuotesModel extends BaseQuotesModel {
804
805
  let step
805
806
  try {
806
807
  step = 'axios-request-1'
807
- return axios.request(options)
808
+ return await httpRequestBase(options, axios)
808
809
  } catch (err) {
809
810
  this.log.warn('error in sendHttpRequest: ', err)
810
811
  const extensions = err.extensions || []
@@ -46,7 +46,7 @@ const Metrics = require('@mojaloop/central-services-metrics')
46
46
  const LOCAL_ENUM = require('../lib/enum')
47
47
  const dto = require('../lib/dto')
48
48
 
49
- const { httpRequest } = require('../lib/http')
49
+ const { httpRequest, httpRequestBase } = require('../lib/http')
50
50
  const { RESOURCES } = require('../constants')
51
51
  const BaseQuotesModel = require('./BaseQuotesModel')
52
52
 
@@ -1035,7 +1035,7 @@ class QuotesModel extends BaseQuotesModel {
1035
1035
  try {
1036
1036
  super.addFspiopSignatureHeader(opts)
1037
1037
  step = 'axios-request-2'
1038
- res = await axios.request(opts)
1038
+ res = await httpRequestBase(opts, axios)
1039
1039
  // todo: use wrapper on axios
1040
1040
  histTimer({ success: true, queryName: 'quote_sendErrorCallback' })
1041
1041
  } catch (err) {