diff --git a/src/handlers/notification/index.js b/src/handlers/notification/index.js index 6b52d3ca..5d992097 100644 --- a/src/handlers/notification/index.js +++ b/src/handlers/notification/index.js @@ -319,8 +319,8 @@ const processMessage = async (msg, span) => { } histTimerEndSendRequest({ success: true, from, dest: to, action, status: response.status }) - // send an extra notification back to the original sender (if enabled in config) - if (Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE) { + // send an extra notification back to the original sender (if enabled in config) and ignore this for on-us transfers + if (Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE && from !== to) { const callbackURLFrom = await Participant.getEndpoint(from, ENUM.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_TRANSFER_PUT, id, span) Logger.isDebugEnabled && Logger.debug(`Notification::processMessage - Callback.sendRequest(${callbackURLFrom}, ${ENUM.Http.RestMethods.PUT}, ${JSON.stringify(callbackHeaders)}, ${payloadForCallback}, ${id}, ${ENUM.Http.Headers.FSPIOP.SWITCH.value}, ${from})`) callbackHeaders = createCallbackHeaders({ dfspId: from, transferId: id, headers: content.headers, httpMethod: ENUM.Http.RestMethods.PUT, endpointTemplate: ENUM.EndPoints.FspEndpointTemplates.TRANSFERS_PUT }, fromSwitch) @@ -366,8 +366,8 @@ const processMessage = async (msg, span) => { Logger.isDebugEnabled && Logger.debug(`Notification::processMessage - Callback.sendRequest(${callbackURLTo}, ${ENUM.Http.RestMethods.PUT}, ${JSON.stringify(callbackHeaders)}, ${payloadForCallback}, ${id}, ${from}, ${to})`) await Callback.sendRequest(callbackURLTo, callbackHeaders, from, to, ENUM.Http.RestMethods.PUT, payloadForCallback, ENUM.Http.ResponseTypes.JSON, span) - // send an extra notification back to the original sender (if enabled in config) - if (Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE) { + // send an extra notification back to the original sender (if enabled in config) and ignore this for on-us transfers + if (Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE && from !== to) { jwsSigner = getJWSSigner(ENUM.Http.Headers.FSPIOP.SWITCH.value) Logger.isDebugEnabled && Logger.debug(`Notification::processMessage - Callback.sendRequest(${callbackURLFrom}, ${ENUM.Http.RestMethods.PUT}, ${JSON.stringify(callbackHeaders)}, ${payloadForCallback}, ${id}, ${ENUM.Http.Headers.FSPIOP.SWITCH.value}, ${from})`) callbackHeaders = createCallbackHeaders({ dfspId: from, transferId: id, headers: content.headers, httpMethod: ENUM.Http.RestMethods.PUT, endpointTemplate: ENUM.EndPoints.FspEndpointTemplates.TRANSFERS_PUT }, fromSwitch) @@ -389,8 +389,8 @@ const processMessage = async (msg, span) => { Logger.isDebugEnabled && Logger.debug(`Notification::processMessage - Callback.sendRequest(${callbackURLTo}, ${ENUM.Http.RestMethods.PUT}, ${JSON.stringify(callbackHeaders)}, ${payloadForCallback}, ${id}, ${from}, ${to})`) await Callback.sendRequest(callbackURLTo, callbackHeaders, from, to, ENUM.Http.RestMethods.PUT, payloadForCallback, ENUM.Http.ResponseTypes.JSON, span) - // send an extra notification back to the original sender (if enabled in config) - if (Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE) { + // send an extra notification back to the original sender (if enabled in config) and ignore this for on-us transfers + if (Config.SEND_TRANSFER_CONFIRMATION_TO_PAYEE && from !== to) { jwsSigner = getJWSSigner(ENUM.Http.Headers.FSPIOP.SWITCH.value) Logger.isDebugEnabled && Logger.debug(`Notification::processMessage - Callback.sendRequest(${callbackURLFrom}, ${ENUM.Http.RestMethods.PUT}, ${JSON.stringify(callbackHeaders)}, ${payloadForCallback}, ${id}, ${ENUM.Http.Headers.FSPIOP.SWITCH.value}, ${from})`) callbackHeaders = createCallbackHeaders({ dfspId: from, transferId: id, headers: content.headers, httpMethod: ENUM.Http.RestMethods.PUT, endpointTemplate: ENUM.EndPoints.FspEndpointTemplates.TRANSFERS_PUT_ERROR }, fromSwitch) diff --git a/test/unit/handlers/notification/index.test.js b/test/unit/handlers/notification/index.test.js index caa2dad9..1889883d 100644 --- a/test/unit/handlers/notification/index.test.js +++ b/test/unit/handlers/notification/index.test.js @@ -727,6 +727,74 @@ Test('Notification Service tests', async notificationTest => { test.end() }) + processMessageTest.test('should not send notification to sender even if "SEND_TRANSFER_CONFIRMATION_TO_PAYEE" is enabled for on-us transfers', async test => { + const ConfigStub = Util.clone(Config) + ConfigStub.SEND_TRANSFER_CONFIRMATION_TO_PAYEE = true + const NotificationProxy = Proxyquire(`${src}/handlers/notification`, { + '../../lib/config': ConfigStub + }) + const payerFsp = 'dfsp1' + const payeeFsp = 'dfsp1' + const uuid = Uuid() + const msg = { + value: { + metadata: { + event: { + type: 'notification', + action: 'commit', + state: { + status: 'success', + code: 0 + } + } + }, + content: { + headers: { + 'FSPIOP-Destination': payeeFsp, + 'FSPIOP-Source': payerFsp + }, + payload: { transferId: uuid } + }, + to: payeeFsp, + from: payerFsp, + id: 'b51ec534-ee48-4575-b6a9-ead2955b8098' + } + } + + const method = ENUM.Http.RestMethods.PUT + let fromUrl = await Participant.getEndpoint(msg.value.from, ENUM.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_TRANSFER_PUT, msg.value.content.payload.transferId) + let toUrl = await Participant.getEndpoint(msg.value.to, ENUM.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_TRANSFER_PUT, msg.value.content.payload.transferId) + let fromHeaders = createCallbackHeaders({ dfspId: msg.value.from, transferId: msg.value.content.payload.transferId, headers: msg.value.content.headers, httpMethod: method, endpointTemplate: ENUM.EndPoints.FspEndpointTemplates.TRANSFERS_PUT }, true) + let toHeaders = createCallbackHeaders({ dfspId: msg.value.to, transferId: msg.value.content.payload.transferId, headers: msg.value.content.headers, httpMethod: method, endpointTemplate: ENUM.EndPoints.FspEndpointTemplates.TRANSFERS_PUT }) + const message = { transferId: uuid } + + Callback.sendRequest.withArgs(fromUrl, fromHeaders, ENUM.Http.Headers.FSPIOP.SWITCH.value, msg.value.from, method, JSON.stringify(message), 'json').returns(Promise.resolve(200)) + + // test for "commit" action and "success" status + await NotificationProxy.processMessage(msg) + test.ok(Callback.sendRequest.calledWith(toUrl, toHeaders, msg.value.from, msg.value.to, method, JSON.stringify(message))) + test.notok(Callback.sendRequest.calledWith(fromUrl, fromHeaders, ENUM.Http.Headers.FSPIOP.SWITCH.value, msg.value.from, method, JSON.stringify(message))) + + // test for "reject" action + msg.value.metadata.event.action = 'reject' + await NotificationProxy.processMessage(msg) + test.ok(Callback.sendRequest.calledWith(toUrl, toHeaders, msg.value.from, msg.value.to, method, JSON.stringify(message))) + test.notok(Callback.sendRequest.calledWith(fromUrl, fromHeaders, ENUM.Http.Headers.FSPIOP.SWITCH.value, msg.value.from, method, JSON.stringify(message))) + + fromUrl = await Participant.getEndpoint(msg.value.from, ENUM.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_TRANSFER_ERROR, msg.value.content.payload.transferId) + toUrl = await Participant.getEndpoint(msg.value.to, ENUM.EndPoints.FspEndpointTypes.FSPIOP_CALLBACK_URL_TRANSFER_ERROR, msg.value.content.payload.transferId) + fromHeaders = createCallbackHeaders({ dfspId: msg.value.from, transferId: msg.value.content.payload.transferId, headers: msg.value.content.headers, httpMethod: method, endpointTemplate: ENUM.EndPoints.FspEndpointTemplates.TRANSFERS_PUT_ERROR }, true) + toHeaders = createCallbackHeaders({ dfspId: msg.value.to, transferId: msg.value.content.payload.transferId, headers: msg.value.content.headers, httpMethod: method, endpointTemplate: ENUM.EndPoints.FspEndpointTemplates.TRANSFERS_PUT_ERROR }) + + // test for "abort" action + msg.value.metadata.event.action = 'abort' + await NotificationProxy.processMessage(msg) + test.notok(Callback.sendRequest.calledWith(fromUrl, fromHeaders, ENUM.Http.Headers.FSPIOP.SWITCH.value, msg.value.from, method, JSON.stringify(message))) + test.ok(Callback.sendRequest.calledWith(toUrl, toHeaders, msg.value.from, msg.value.to, method, JSON.stringify(message))) + + test.end() + }) + await processMessageTest.test('warn if invalid action received from kafka', async test => { const CentralServicesLoggerStub = { error: sandbox.stub().returns(Promise.resolve()),