@mojaloop/central-ledger 19.13.0 → 19.14.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.
@@ -1,11 +1,32 @@
1
1
  'use strict'
2
2
 
3
- const FiveBellsCondition = require('five-bells-condition')
4
3
  const ErrorHandler = require('@mojaloop/central-services-error-handling')
5
4
 
6
- const validateCondition = (conditionUri) => {
5
+ /**
6
+ * @function validateCondition
7
+ * @description Validate that the condition is a valid 32-byte base64 encoded string.
8
+ *
9
+ * Reference: https://docs.mojaloop.io/api/fspiop/v1.1/api-definition.html#conditional-transfers
10
+ *
11
+ * ILP supports a variety of conditions for performing a conditional payment, but implementers of
12
+ * the API should use the SHA-256 hash of a 32-byte pre-image. The condition attached to the transfer
13
+ * is the SHA-256 hash and the fulfilment of that condition is the pre-image. Therefore, if the
14
+ * condition attached to a transfer is a SHA-256 hash, then when a fulfilment is submitted for
15
+ * that transaction, the ledger will validate it by calculating the SHA-256 hash of the fulfilment
16
+ * and ensuring that the hash is equal to the condition.
17
+ */
18
+ const validateCondition = (condition) => {
7
19
  try {
8
- return FiveBellsCondition.validateCondition(conditionUri)
20
+ if (!condition) {
21
+ throw new Error('Condition not defined.')
22
+ }
23
+
24
+ const conditionBuffer = Buffer.from(condition, 'base64')
25
+ if (conditionBuffer.length !== 32) {
26
+ throw new Error(`Expected condition to have length of 32, found: ${conditionBuffer.length}.`)
27
+ }
28
+
29
+ return true
9
30
  } catch (err) {
10
31
  throw ErrorHandler.Factory.reformatFSPIOPError(err)
11
32
  }
@@ -413,7 +413,23 @@ const processFulfilMessage = async (message, functionality, span) => {
413
413
  }
414
414
 
415
415
  Util.breadcrumb(location, { path: 'validationCheck' })
416
- if (payload.fulfilment && !Validator.validateFulfilCondition(payload.fulfilment, transfer.condition)) {
416
+ // Skip fulfilment validation for actions that use errorInformation instead of fulfilment
417
+ const actionsSkippingFulfilmentValidation = [
418
+ TransferEventAction.ABORT,
419
+ TransferEventAction.BULK_ABORT,
420
+ TransferEventAction.REJECT
421
+ ]
422
+ const skipValidation = actionsSkippingFulfilmentValidation.includes(action)
423
+
424
+ if (skipValidation) {
425
+ Logger.isInfoEnabled && Logger.info(Util.breadcrumb(location, `Skipping fulfilment validation for action--${actionLetter}9`))
426
+ }
427
+ const isInvalid =
428
+ !skipValidation &&
429
+ (!payload.fulfilment ||
430
+ !Validator.validateFulfilCondition(payload.fulfilment, transfer.condition))
431
+
432
+ if (isInvalid) {
417
433
  Logger.isInfoEnabled && Logger.info(Util.breadcrumb(location, `callbackErrorInvalidFulfilment--${actionLetter}9`))
418
434
  const fspiopError = ErrorHandler.Factory.createFSPIOPError(ErrorHandler.Enums.FSPIOPErrorCodes.VALIDATION_ERROR, 'invalid fulfilment')
419
435
  const apiFSPIOPError = fspiopError.toApiErrorObject(Config.ERROR_HANDLING)
@@ -165,8 +165,7 @@ const validateConditionAndExpiration = async (payload) => {
165
165
  return false
166
166
  }
167
167
  try {
168
- const condition = 'ni:///sha-256;' + payload.condition + '?fpt=preimage-sha-256&cost=0'
169
- await CryptoConditions.validateCondition(condition)
168
+ CryptoConditions.validateCondition(payload.condition)
170
169
  } catch (err) {
171
170
  Logger.isErrorEnabled && Logger.error(`${err.message}`)
172
171
  reasons.push('Condition validation failed')