From 225b9d4386bd99295c57d4d4ed9a8b564b5823ea Mon Sep 17 00:00:00 2001 From: Steven Oderayi Date: Wed, 21 Aug 2024 09:31:29 +0100 Subject: [PATCH] fix: restore proxied quotes validation --- src/model/quotes.js | 10 ++++++++-- test/integration/putCallback.test.js | 4 ++-- test/unit/model/quotes.test.js | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/model/quotes.js b/src/model/quotes.js index 6bb4b7a6..3ba51f90 100644 --- a/src/model/quotes.js +++ b/src/model/quotes.js @@ -175,7 +175,11 @@ class QuotesModel { // In fspiop api spec 2.0, to support FX, `supportedCurrencies` can be optionally passed in via the payer property. // If `supportedCurrencies` is present, then payer FSP must have position accounts for all those currencies. - if (quoteRequest.payer.supportedCurrencies && quoteRequest.payer.supportedCurrencies.length > 0) { + if (quoteRequest.payer.supportedCurrencies && + quoteRequest.payer.supportedCurrencies.length > 0 && + // if the payer dfsp has a proxy cache entry, we do not validate the dfsp here + !(await this.proxyClient?.lookupProxyByDfspId(fspiopSource)) + ) { await Promise.all(quoteRequest.payer.supportedCurrencies.map(currency => this.db.getParticipant(fspiopSource, LOCAL_ENUM.PAYER_DFSP, currency, ENUM.Accounts.LedgerAccountType.POSITION) )) @@ -192,7 +196,9 @@ class QuotesModel { // Lets make sure the optional fspId exists in the payer's partyIdInfo before we validate it if ( quoteRequest.payer?.partyIdInfo?.fspId && - quoteRequest.payer.partyIdInfo.fspId !== fspiopSource + quoteRequest.payer.partyIdInfo.fspId !== fspiopSource && + // if the payer dfsp has a proxy cache entry, we do not validate the dfsp here + !(await this.proxyClient?.lookupProxyByDfspId(quoteRequest.payer.partyIdInfo.fspId)) ) { await this.db.getParticipant(quoteRequest.payer.partyIdInfo.fspId, LOCAL_ENUM.PAYER_DFSP, quoteRequest.amount.currency, ENUM.Accounts.LedgerAccountType.POSITION) } diff --git a/test/integration/putCallback.test.js b/test/integration/putCallback.test.js index 454a2969..3502b51f 100644 --- a/test/integration/putCallback.test.js +++ b/test/integration/putCallback.test.js @@ -125,7 +125,7 @@ describe('PUT callback Tests --> ', () => { expect(protectedHeader).toBeTruthy() }) - test('should pass validation for PUT /quotes/{ID} request if request transferAmount/payeeReceiveAmount currency is registered (position account exists) for the payee pariticpant', async () => { + test('should pass validation for PUT /quotes/{ID} request if request transferAmount/payeeReceiveAmount currency is registered (position account exists) for the payee participant', async () => { // create test quote to prevent db (row reference) error on PUT request const quoteCreated = await createQuote() await wait(WAIT_TIMEOUT) @@ -194,7 +194,7 @@ describe('PUT callback Tests --> ', () => { } }) - test('should fail validation for PUT /quotes/{ID} request if request transferAmount/payeeReceiveAmount currency is not registered (position account does not exist) for the payee pariticpant', async () => { + test('should fail validation for PUT /quotes/{ID} request if request transferAmount/payeeReceiveAmount currency is not registered (position account does not exist) for the payee participant', async () => { // test the same scenario with only transferAmount set // create test quote to prevent db (row reference) error on PUT request const quoteCreated = await createQuote() diff --git a/test/unit/model/quotes.test.js b/test/unit/model/quotes.test.js index 86583a58..6d2c1e58 100644 --- a/test/unit/model/quotes.test.js +++ b/test/unit/model/quotes.test.js @@ -644,6 +644,27 @@ describe('QuotesModel', () => { expect(quotesModel.db.getParticipant).toHaveBeenCalledWith(fspiopSource, 'PAYER_DFSP', 'ZMW', Enum.Accounts.LedgerAccountType.POSITION) expect(quotesModel.db.getParticipant).toHaveBeenCalledWith(fspiopSource, 'PAYER_DFSP', 'TZS', Enum.Accounts.LedgerAccountType.POSITION) }) + + it('should skip validating source if source is a proxied participant', async () => { + const fspiopSource = 'dfsp1' + const fspiopDestination = 'dfsp2' + const request = mockData.quoteRequest + request.payer.supportedCurrencies = ['ZMW', 'TZS'] + + quotesModel.proxyClient = { + isConnected: false, + connect: jest.fn().mockResolvedValue(true), + lookupProxyByDfspId: jest.fn().mockImplementation(fspid => { + return fspid === fspiopSource ? 'proxyId' : undefined + }) + } + + await expect(quotesModel.validateQuoteRequest(fspiopSource, fspiopDestination, request)).resolves.toBeUndefined() + + quotesModel.db.getParticipant.mock.calls.forEach(call => { + expect(call[0]).not.toBe(fspiopSource) + }) + }) }) describe('validateQuoteUpdate', () => { beforeEach(() => {