diff --git a/.ncurc.yaml b/.ncurc.yaml index 9f4ddec7b..10735f580 100644 --- a/.ncurc.yaml +++ b/.ncurc.yaml @@ -12,5 +12,4 @@ reject: [ "sinon", # glob >= 11 requires node >= 20 "glob", - "@mojaloop/central-services-shared", ## todo: temporary!!!! ] diff --git a/audit-ci.jsonc b/audit-ci.jsonc index 6915f272d..9314e72e9 100644 --- a/audit-ci.jsonc +++ b/audit-ci.jsonc @@ -4,19 +4,14 @@ // Only use one of ["low": true, "moderate": true, "high": true, "critical": true] "moderate": true, "allowlist": [ // NOTE: Please add as much information as possible to any items added to the allowList - "GHSA-w5p7-h5w8-2hfq", // tap-spec>tap-out>trim; This has been analyzed and this is acceptable as it is used to run tests. - "GHSA-2mvq-xp48-4c77", // https://github.com/advisories/GHSA-2mvq-xp48-4c77 - "GHSA-5854-jvxx-2cg9", // https://github.com/advisories/GHSA-5854-jvxx-2cg9 - "GHSA-7hx8-2rxv-66xv", // https://github.com/advisories/GHSA-7hx8-2rxv-66xv - "GHSA-c429-5p7v-vgjp", // https://github.com/advisories/GHSA-c429-5p7v-vgjp - "GHSA-g64q-3vg8-8f93", // https://github.com/advisories/GHSA-g64q-3vg8-8f93 - "GHSA-mg85-8mv5-ffjr", // https://github.com/advisories/GHSA-mg85-8mv5-ffjr - "GHSA-8hc4-vh64-cxmj", // https://github.com/advisories/GHSA-8hc4-vh64-cxmj - "GHSA-952p-6rrq-rcjv", // https://github.com/advisories/GHSA-952p-6rrq-rcjv - "GHSA-9wv6-86v2-598j", // https://github.com/advisories/GHSA-9wv6-86v2-598j - "GHSA-qwcr-r2fm-qrc7", // https://github.com/advisories/GHSA-qwcr-r2fm-qrc7 - "GHSA-cm22-4g7w-348p", // https://github.com/advisories/GHSA-cm22-4g7w-348p - "GHSA-m6fv-jmcg-4jfg", // https://github.com/advisories/GHSA-m6fv-jmcg-4jfg - "GHSA-qw6h-vgh9-j6wx" // https://github.com/advisories/GHSA-qw6h-vgh9-j6wx + "GHSA-w5p7-h5w8-2hfq", // tap-spec>tap-out>trim; This has been analyzed and this is acceptable as it is used to run tests. + "GHSA-2mvq-xp48-4c77", // https://github.com/advisories/GHSA-2mvq-xp48-4c77 + "GHSA-5854-jvxx-2cg9", // https://github.com/advisories/GHSA-5854-jvxx-2cg9 + "GHSA-7hx8-2rxv-66xv", // https://github.com/advisories/GHSA-7hx8-2rxv-66xv + "GHSA-c429-5p7v-vgjp", // https://github.com/advisories/GHSA-c429-5p7v-vgjp + "GHSA-g64q-3vg8-8f93", // https://github.com/advisories/GHSA-g64q-3vg8-8f93 + "GHSA-mg85-8mv5-ffjr", // https://github.com/advisories/GHSA-mg85-8mv5-ffjr + "GHSA-8hc4-vh64-cxmj", // https://github.com/advisories/GHSA-8hc4-vh64-cxmj + "GHSA-952p-6rrq-rcjv" // https://github.com/advisories/GHSA-952p-6rrq-rcjv ] } diff --git a/migrations/960100_create_externalParticipant.js b/migrations/960100_create_externalParticipant.js deleted file mode 100644 index a0f4ab5f7..000000000 --- a/migrations/960100_create_externalParticipant.js +++ /dev/null @@ -1,47 +0,0 @@ -/***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Eugen Klymniuk - -------------- - **********/ - -exports.up = async (knex) => { - return knex.schema.hasTable('externalParticipant').then(function(exists) { - if (!exists) { - return knex.schema.createTable('externalParticipant', (t) => { - t.bigIncrements('externalParticipantId').primary().notNullable() - t.string('name', 30).notNullable() - t.unique('name') - t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable() - t.integer('proxyId').unsigned().notNullable() - t.foreign('proxyId').references('participantId').inTable('participant') - }) - } - }) -} - -exports.down = function (knex) { - return knex.schema.hasTable('externalParticipant').then(function(exists) { - if (!exists) { - return knex.schema.dropTableIfExists('externalParticipant') - } - }) -} diff --git a/migrations/960110_alter_transferParticipant__addFiled_externalParticipantId.js b/migrations/960110_alter_transferParticipant__addFiled_externalParticipantId.js deleted file mode 100644 index 13b01119e..000000000 --- a/migrations/960110_alter_transferParticipant__addFiled_externalParticipantId.js +++ /dev/null @@ -1,50 +0,0 @@ -/***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Eugen Klymniuk - -------------- - **********/ - -const EP_ID_FIELD = 'externalParticipantId' - -exports.up = async (knex) => { - return knex.schema.hasTable('transferParticipant').then(function(exists) { - if (exists) { - return knex.schema.alterTable('transferParticipant', (t) => { - t.bigint(EP_ID_FIELD).unsigned().nullable() - t.foreign(EP_ID_FIELD).references(EP_ID_FIELD).inTable('externalParticipant') - t.index(EP_ID_FIELD) - }) - } - }) -} - -exports.down = async (knex) => { - return knex.schema.hasTable('transferParticipant').then(function(exists) { - if (exists) { - return knex.schema.alterTable('transferParticipant', (t) => { - t.dropIndex(EP_ID_FIELD) - t.dropForeign(EP_ID_FIELD) - t.dropColumn(EP_ID_FIELD) - }) - } - }) -} diff --git a/migrations/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js b/migrations/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js deleted file mode 100644 index ecf4adefd..000000000 --- a/migrations/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js +++ /dev/null @@ -1,50 +0,0 @@ -/***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Eugen Klymniuk - -------------- - **********/ - -const EP_ID_FIELD = 'externalParticipantId' - -exports.up = async (knex) => { - return knex.schema.hasTable('fxTransferParticipant').then((exists) => { - if (exists) { - return knex.schema.alterTable('fxTransferParticipant', (t) => { - t.bigint(EP_ID_FIELD).unsigned().nullable() - t.foreign(EP_ID_FIELD).references(EP_ID_FIELD).inTable('externalParticipant') - t.index(EP_ID_FIELD) - }) - } - }) -} - -exports.down = async (knex) => { - return knex.schema.hasTable('fxTransferParticipant').then((exists) => { - if (exists) { - return knex.schema.alterTable('fxTransferParticipant', (t) => { - t.dropIndex(EP_ID_FIELD) - t.dropForeign(EP_ID_FIELD) - t.dropColumn(EP_ID_FIELD) - }) - } - }) -} diff --git a/package-lock.json b/package-lock.json index f58971f5d..bef1d808d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1684,6 +1684,12 @@ "@hapi/hoek": "9.x.x" } }, + "node_modules/@mojaloop/central-services-shared/node_modules/@hapi/boom/node_modules/@hapi/hoek": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.3.tgz", + "integrity": "sha512-jKtjLLDiH95b002sJVc5c74PE6KKYftuyVdVmsuYId5stTaWcRFqE+5ukZI4gDUKjGn8wv2C3zPn3/nyjEI7gg==", + "deprecated": "This version has been deprecated and is no longer supported or maintained" + }, "node_modules/@mojaloop/central-services-shared/node_modules/@hapi/catbox-memory": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@hapi/catbox-memory/-/catbox-memory-5.0.1.tgz", @@ -1693,10 +1699,25 @@ "@hapi/hoek": "9.x.x" } }, - "node_modules/@mojaloop/central-services-shared/node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + "node_modules/@mojaloop/central-services-shared/node_modules/@hapi/catbox-memory/node_modules/@hapi/hoek": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.3.tgz", + "integrity": "sha512-jKtjLLDiH95b002sJVc5c74PE6KKYftuyVdVmsuYId5stTaWcRFqE+5ukZI4gDUKjGn8wv2C3zPn3/nyjEI7gg==", + "deprecated": "This version has been deprecated and is no longer supported or maintained" + }, + "node_modules/@mojaloop/central-services-shared/node_modules/raw-body": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } }, "node_modules/@mojaloop/central-services-stream": { "version": "11.3.1", @@ -2741,20 +2762,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/body-parser/node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -3004,24 +3011,20 @@ } }, "node_modules/cheerio": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", - "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "encoding-sniffer": "^0.2.0", - "htmlparser2": "^9.1.0", - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^6.19.5", - "whatwg-mimetype": "^4.0.0" + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" }, "engines": { - "node": ">=18.17" + "node": ">= 6" }, "funding": { "url": "https://github.com/cheeriojs/cheerio?sponsor=1" @@ -4119,6 +4122,17 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -4417,16 +4431,14 @@ "node": ">= 0.8" } }, - "node_modules/encoding-sniffer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", - "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "peer": true, "dependencies": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - }, - "funding": { - "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + "iconv-lite": "^0.6.2" } }, "node_modules/end-of-stream": { @@ -4438,12 +4450,9 @@ } }, "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "engines": { - "node": ">=0.12" - }, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -5488,6 +5497,17 @@ "node": ">=4.8" } }, + "node_modules/execa/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/execa/node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -6306,17 +6326,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -6993,9 +7002,9 @@ "dev": true }, "node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -7006,8 +7015,19 @@ "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/http-errors": { @@ -7946,6 +7966,48 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-processinfo/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/istanbul-lib-processinfo/node_modules/p-map": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", @@ -7958,6 +8020,21 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", @@ -8045,9 +8122,9 @@ } }, "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -8498,7 +8575,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dev": true, "dependencies": { "uc.micro": "^2.0.0" } @@ -8506,8 +8582,7 @@ "node_modules/linkify-it/node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" }, "node_modules/load-json-file": { "version": "5.3.0", @@ -8723,7 +8798,6 @@ "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", - "dev": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -8746,6 +8820,17 @@ "markdown-it": "*" } }, + "node_modules/markdown-it-attrs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-1.2.1.tgz", + "integrity": "sha512-EYYKLF9RvQJx1Etsb6EsBGWL7qNQLpg9BRej5f06+UdX75T5gvldEn7ts6bkLIQqugE15SGn4lw1CXDS1A+XUA==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "markdown-it": ">=7.0.1" + } + }, "node_modules/markdown-it-emoji": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz", @@ -8756,17 +8841,26 @@ "resolved": "https://registry.npmjs.org/markdown-it-lazy-headers/-/markdown-it-lazy-headers-0.1.3.tgz", "integrity": "sha512-65BxqvmYLpVifv6MvTElthY8zvZ/TpZBCdshr/mTpsFkqwcwWtfD3YoSE7RYSn7ugnEAAaj2gywszq+hI/Pxgg==" }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/markdown-it/node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" }, "node_modules/markdown-it/node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" }, "node_modules/marked": { "version": "4.3.0", @@ -9861,6 +9955,21 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/nyc/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -10222,9 +10331,9 @@ } }, "node_modules/openapi-sampler": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.5.1.tgz", - "integrity": "sha512-tIWIrZUKNAsbqf3bd9U1oH6JEXo8LNYuDlXw26By67EygpjT+ArFnsxxyTMjFWRfbqo5ozkvgSQDK69Gd8CddA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.3.1.tgz", + "integrity": "sha512-Ert9mvc2tLPmmInwSyGZS+v4Ogu9/YoZuq9oP3EdUklg2cad6+IGndP9yqJJwbgdXwZibiq5fpv6vYujchdJFg==", "dependencies": { "@types/json-schema": "^7.0.7", "json-pointer": "0.6.2" @@ -10444,15 +10553,15 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", - "dependencies": { - "parse5": "^7.0.0" + "node_modules/parse5/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" }, "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/parseurl": { @@ -10736,9 +10845,9 @@ } }, "node_modules/postcss": { - "version": "8.4.45", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", - "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "funding": [ { "type": "opencollective", @@ -10755,7 +10864,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", + "picocolors": "^1.0.0", "source-map-js": "^1.2.0" }, "engines": { @@ -10990,7 +11099,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, "engines": { "node": ">=6" } @@ -11061,19 +11169,30 @@ } }, "node_modules/raw-body": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", - "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", - "iconv-lite": "0.6.3", + "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "engines": { "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -11851,65 +11970,6 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12018,24 +12078,6 @@ "postcss": "^8.3.11" } }, - "node_modules/sanitize-html/node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -12248,14 +12290,6 @@ "wordwrap": "0.0.2" } }, - "node_modules/shins/node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/shins/node_modules/linkify-it": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", @@ -12279,17 +12313,6 @@ "markdown-it": "bin/markdown-it.js" } }, - "node_modules/shins/node_modules/markdown-it-attrs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/markdown-it-attrs/-/markdown-it-attrs-1.2.1.tgz", - "integrity": "sha512-EYYKLF9RvQJx1Etsb6EsBGWL7qNQLpg9BRej5f06+UdX75T5gvldEn7ts6bkLIQqugE15SGn4lw1CXDS1A+XUA==", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "markdown-it": ">=7.0.1" - } - }, "node_modules/shins/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -12506,9 +12529,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "engines": { "node": ">=0.10.0" } @@ -12550,6 +12573,16 @@ "node": ">=8" } }, + "node_modules/spawn-wrap/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/spawn-wrap/node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -12563,6 +12596,53 @@ "node": ">=8.0.0" } }, + "node_modules/spawn-wrap/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/spawn-wrap/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/spawn-wrap/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/spawn-wrap/node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -14132,14 +14212,6 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, - "node_modules/undici": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", - "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", - "engines": { - "node": ">=18.17" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -14275,25 +14347,6 @@ "node": ">=12" } }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "engines": { - "node": ">=18" - } - }, "node_modules/whatwg-url": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", @@ -14455,14 +14508,6 @@ "wrap-ansi": "^2.0.0" } }, - "node_modules/widdershins/node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/widdershins/node_modules/find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", diff --git a/src/handlers/transfers/createRemittanceEntity.js b/src/handlers/transfers/createRemittanceEntity.js index c520ce3c5..1c35f18fa 100644 --- a/src/handlers/transfers/createRemittanceEntity.js +++ b/src/handlers/transfers/createRemittanceEntity.js @@ -1,9 +1,6 @@ const fxTransferModel = require('../../models/fxTransfer') const TransferService = require('../../domain/transfer') const cyril = require('../../domain/fx/cyril') -const { logger } = require('../../shared/logger') - -/** @import { ProxyObligation } from './prepare.js' */ // abstraction on transfer and fxTransfer const createRemittanceEntity = (isFx) => { @@ -21,16 +18,6 @@ const createRemittanceEntity = (isFx) => { : TransferService.saveTransferDuplicateCheck(id, hash) }, - /** - * Saves prepare transfer/fxTransfer details to DB. - * - * @param {Object} payload - Message payload. - * @param {string | null} reason - Validation failure reasons. - * @param {Boolean} isValid - isValid. - * @param {DeterminingTransferCheckResult} determiningTransferCheckResult - The determining transfer check result. - * @param {ProxyObligation} proxyObligation - The proxy obligation - * @returns {Promise} - */ async savePreparedRequest ( payload, reason, @@ -38,6 +25,7 @@ const createRemittanceEntity = (isFx) => { determiningTransferCheckResult, proxyObligation ) { + // todo: add histoTimer and try/catch here return isFx ? fxTransferModel.fxTransfer.savePreparedRequest( payload, @@ -61,38 +49,16 @@ const createRemittanceEntity = (isFx) => { : TransferService.getByIdLight(id) }, - /** - * A determiningTransferCheckResult. - * @typedef {Object} DeterminingTransferCheckResult - * @property {boolean} determiningTransferExists - Indicates if the determining transfer exists. - * @property {Array<{participantName, currencyId}>} participantCurrencyValidationList - List of validations for participant currencies. - * @property {Object} [transferRecord] - Determining transfer for the FX transfer (optional). - * @property {Array} [watchListRecords] - Records from fxWatchList-table for the transfer (optional). - */ - /** - * Checks if a determining transfer exists based on the payload and proxy obligation. - * The function determines which method to use based on whether it is an FX transfer. - * - * @param {Object} payload - The payload data required for the transfer check. - * @param {ProxyObligation} proxyObligation - The proxy obligation details. - * @returns {DeterminingTransferCheckResult} determiningTransferCheckResult - */ async checkIfDeterminingTransferExists (payload, proxyObligation) { - const result = isFx - ? await cyril.checkIfDeterminingTransferExistsForFxTransferMessage(payload, proxyObligation) - : await cyril.checkIfDeterminingTransferExistsForTransferMessage(payload, proxyObligation) - - logger.debug('cyril determiningTransferCheckResult:', { result }) - return result + return isFx + ? cyril.checkIfDeterminingTransferExistsForFxTransferMessage(payload, proxyObligation) + : cyril.checkIfDeterminingTransferExistsForTransferMessage(payload, proxyObligation) }, async getPositionParticipant (payload, determiningTransferCheckResult, proxyObligation) { - const result = isFx - ? await cyril.getParticipantAndCurrencyForFxTransferMessage(payload, determiningTransferCheckResult) - : await cyril.getParticipantAndCurrencyForTransferMessage(payload, determiningTransferCheckResult, proxyObligation) - - logger.debug('cyril getPositionParticipant result:', { result }) - return result + return isFx + ? cyril.getParticipantAndCurrencyForFxTransferMessage(payload, determiningTransferCheckResult) + : cyril.getParticipantAndCurrencyForTransferMessage(payload, determiningTransferCheckResult, proxyObligation) }, async logTransferError (id, errorCode, errorDescription) { diff --git a/src/handlers/transfers/dto.js b/src/handlers/transfers/dto.js index 1f1edcd41..6d4b5859f 100644 --- a/src/handlers/transfers/dto.js +++ b/src/handlers/transfers/dto.js @@ -16,10 +16,10 @@ const prepareInputDto = (error, messages) => { if (!message) throw new Error('No input kafka message') const payload = decodePayload(message.value.content.payload) + const isForwarded = message.value.metadata.event.action === Action.FORWARDED || message.value.metadata.event.action === Action.FX_FORWARDED const isFx = !payload.transferId const { action } = message.value.metadata.event - const isForwarded = [Action.FORWARDED, Action.FX_FORWARDED].includes(action) const isPrepare = [Action.PREPARE, Action.FX_PREPARE, Action.FORWARDED, Action.FX_FORWARDED].includes(action) const actionLetter = isPrepare diff --git a/src/handlers/transfers/prepare.js b/src/handlers/transfers/prepare.js index 5809feb52..a6bfa9208 100644 --- a/src/handlers/transfers/prepare.js +++ b/src/handlers/transfers/prepare.js @@ -41,7 +41,7 @@ const ProxyCache = require('#src/lib/proxyCache') const FxTransferService = require('#src/domain/fx/index') const { Kafka, Comparators } = Util -const { TransferState, TransferInternalState } = Enum.Transfers +const { TransferState } = Enum.Transfers const { Action, Type } = Enum.Events.Event const { FSPIOPErrorCodes } = ErrorHandler.Enums const { createFSPIOPError, reformatFSPIOPError } = ErrorHandler.Factory @@ -51,164 +51,6 @@ const consumerCommit = true const fromSwitch = true const proxyEnabled = Config.PROXY_CACHE_CONFIG.enabled -const proceedForwardErrorMessage = async ({ fspiopError, isFx, params }) => { - const eventDetail = { - functionality: Type.NOTIFICATION, - action: isFx ? Action.FX_FORWARDED : Action.FORWARDED - } - await Kafka.proceed(Config.KAFKA_CONFIG, params, { - fspiopError, - eventDetail, - consumerCommit - }) - logger.warn('proceedForwardErrorMessage is done', { fspiopError, eventDetail }) -} - -// think better name -const forwardPrepare = async ({ isFx, params, ID }) => { - if (isFx) { - const fxTransfer = await FxTransferService.getByIdLight(ID) - if (!fxTransfer) { - const fspiopError = ErrorHandler.Factory.createFSPIOPError( - FSPIOPErrorCodes.ID_NOT_FOUND, - 'Forwarded fxTransfer could not be found.' - ).toApiErrorObject(Config.ERROR_HANDLING) - // IMPORTANT: This singular message is taken by the ml-api-adapter and used to - // notify the payerFsp and proxy of the error. - // As long as the `to` and `from` message values are the fsp and fxp, - // and the action is `fx-forwarded`, the ml-api-adapter will notify both. - await proceedForwardErrorMessage({ fspiopError, isFx, params }) - return true - } - - if (fxTransfer.fxTransferState === TransferInternalState.RESERVED) { - await FxTransferService.forwardedFxPrepare(ID) - } else { - const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError( - `Invalid State: ${fxTransfer.fxTransferState} - expected: ${TransferInternalState.RESERVED}` - ).toApiErrorObject(Config.ERROR_HANDLING) - // IMPORTANT: This singular message is taken by the ml-api-adapter and used to - // notify the payerFsp and proxy of the error. - // As long as the `to` and `from` message values are the fsp and fxp, - // and the action is `fx-forwarded`, the ml-api-adapter will notify both. - await proceedForwardErrorMessage({ fspiopError, isFx, params }) - } - } else { - const transfer = await TransferService.getById(ID) - if (!transfer) { - const fspiopError = ErrorHandler.Factory.createFSPIOPError( - FSPIOPErrorCodes.ID_NOT_FOUND, - 'Forwarded transfer could not be found.' - ).toApiErrorObject(Config.ERROR_HANDLING) - // IMPORTANT: This singular message is taken by the ml-api-adapter and used to - // notify the payerFsp and proxy of the error. - // As long as the `to` and `from` message values are the payer and payee, - // and the action is `forwarded`, the ml-api-adapter will notify both. - await proceedForwardErrorMessage({ fspiopError, isFx, params }) - return true - } - - if (transfer.transferState === TransferInternalState.RESERVED) { - await TransferService.forwardedPrepare(ID) - } else { - const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError( - `Invalid State: ${transfer.transferState} - expected: ${TransferInternalState.RESERVED}` - ).toApiErrorObject(Config.ERROR_HANDLING) - // IMPORTANT: This singular message is taken by the ml-api-adapter and used to - // notify the payerFsp and proxy of the error. - // As long as the `to` and `from` message values are the payer and payee, - // and the action is `forwarded`, the ml-api-adapter will notify both. - await proceedForwardErrorMessage({ fspiopError, isFx, params }) - } - } - - return true -} - -/** @import { ProxyOrParticipant } from '#src/lib/proxyCache.js' */ -/** - * @typedef {Object} ProxyObligation - * @property {boolean} isFx - Is FX transfer. - * @property {Object} payloadClone - A clone of the original payload. - * @property {ProxyOrParticipant} initiatingFspProxyOrParticipantId - initiating FSP: proxy or participant. - * @property {ProxyOrParticipant} counterPartyFspProxyOrParticipantId - counterparty FSP: proxy or participant. - * @property {boolean} isInitiatingFspProxy - initiatingFsp.(!inScheme && proxyId !== null). - * @property {boolean} isCounterPartyFspProxy - counterPartyFsp.(!inScheme && proxyId !== null). - */ - -/** - * Calculates proxyObligation. - * @returns {ProxyObligation} proxyObligation - */ -const calculateProxyObligation = async ({ payload, isFx, params, functionality, action }) => { - const proxyObligation = { - isFx, - payloadClone: { ...payload }, - isInitiatingFspProxy: false, - isCounterPartyFspProxy: false, - initiatingFspProxyOrParticipantId: null, - counterPartyFspProxyOrParticipantId: null - } - - if (proxyEnabled) { - const [initiatingFsp, counterPartyFsp] = isFx ? [payload.initiatingFsp, payload.counterPartyFsp] : [payload.payerFsp, payload.payeeFsp] - ;[proxyObligation.initiatingFspProxyOrParticipantId, proxyObligation.counterPartyFspProxyOrParticipantId] = await Promise.all([ - ProxyCache.getFSPProxy(initiatingFsp), - ProxyCache.getFSPProxy(counterPartyFsp) - ]) - logger.debug('Prepare proxy cache lookup results', { - initiatingFsp, - counterPartyFsp, - initiatingFspProxyOrParticipantId: proxyObligation.initiatingFspProxyOrParticipantId, - counterPartyFspProxyOrParticipantId: proxyObligation.counterPartyFspProxyOrParticipantId - }) - - proxyObligation.isInitiatingFspProxy = !proxyObligation.initiatingFspProxyOrParticipantId.inScheme && - proxyObligation.initiatingFspProxyOrParticipantId.proxyId !== null - proxyObligation.isCounterPartyFspProxy = !proxyObligation.counterPartyFspProxyOrParticipantId.inScheme && - proxyObligation.counterPartyFspProxyOrParticipantId.proxyId !== null - - if (isFx) { - proxyObligation.payloadClone.initiatingFsp = !proxyObligation.initiatingFspProxyOrParticipantId?.inScheme && - proxyObligation.initiatingFspProxyOrParticipantId?.proxyId - ? proxyObligation.initiatingFspProxyOrParticipantId.proxyId - : payload.initiatingFsp - proxyObligation.payloadClone.counterPartyFsp = !proxyObligation.counterPartyFspProxyOrParticipantId?.inScheme && - proxyObligation.counterPartyFspProxyOrParticipantId?.proxyId - ? proxyObligation.counterPartyFspProxyOrParticipantId.proxyId - : payload.counterPartyFsp - } else { - proxyObligation.payloadClone.payerFsp = !proxyObligation.initiatingFspProxyOrParticipantId?.inScheme && - proxyObligation.initiatingFspProxyOrParticipantId?.proxyId - ? proxyObligation.initiatingFspProxyOrParticipantId.proxyId - : payload.payerFsp - proxyObligation.payloadClone.payeeFsp = !proxyObligation.counterPartyFspProxyOrParticipantId?.inScheme && - proxyObligation.counterPartyFspProxyOrParticipantId?.proxyId - ? proxyObligation.counterPartyFspProxyOrParticipantId.proxyId - : payload.payeeFsp - } - - // If either debtor participant or creditor participant aren't in the scheme and have no proxy representative, then throw an error. - if ((proxyObligation.initiatingFspProxyOrParticipantId.inScheme === false && proxyObligation.initiatingFspProxyOrParticipantId.proxyId === null) || - (proxyObligation.counterPartyFspProxyOrParticipantId.inScheme === false && proxyObligation.counterPartyFspProxyOrParticipantId.proxyId === null)) { - const fspiopError = ErrorHandler.Factory.createFSPIOPError( - ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, - `Payer proxy or payee proxy not found: initiatingFsp: ${initiatingFsp} counterPartyFsp: ${counterPartyFsp}` - ).toApiErrorObject(Config.ERROR_HANDLING) - await Kafka.proceed(Config.KAFKA_CONFIG, params, { - consumerCommit, - fspiopError, - eventDetail: { functionality, action }, - fromSwitch, - hubName: Config.HUB_NAME - }) - throw fspiopError - } - } - - return proxyObligation -} - const checkDuplication = async ({ payload, isFx, ID, location }) => { const funcName = 'prepare_duplicateCheckComparator' const histTimerDuplicateCheckEnd = Metrics.getHistogram( @@ -238,7 +80,7 @@ const processDuplication = async ({ let error if (!duplication.hasDuplicateHash) { - logger.warn(Util.breadcrumb(location, `callbackErrorModified1--${actionLetter}5`)) + logger.error(Util.breadcrumb(location, `callbackErrorModified1--${actionLetter}5`)) error = createFSPIOPError(FSPIOPErrorCodes.MODIFIED_REQUEST) } else if (action === Action.BULK_PREPARE) { logger.info(Util.breadcrumb(location, `validationError1--${actionLetter}2`)) @@ -322,7 +164,7 @@ const savePreparedRequest = async ({ proxyObligation ) } catch (err) { - logger.error(`${logMessage} error:`, err) + logger.error(`${logMessage} error - ${err.message}`) const fspiopError = reformatFSPIOPError(err, FSPIOPErrorCodes.INTERNAL_SERVER_ERROR) await Kafka.proceed(Config.KAFKA_CONFIG, params, { consumerCommit, @@ -336,9 +178,10 @@ const savePreparedRequest = async ({ } const definePositionParticipant = async ({ isFx, payload, determiningTransferCheckResult, proxyObligation }) => { + console.log(determiningTransferCheckResult) const cyrilResult = await createRemittanceEntity(isFx) .getPositionParticipant(payload, determiningTransferCheckResult, proxyObligation) - + console.log(cyrilResult) let messageKey // On a proxied transfer prepare if there is a corresponding fx transfer `getPositionParticipant` // should return the fxp's proxy as the participantName since the fxp proxy would be saved as the counterPartyFsp @@ -349,6 +192,8 @@ const definePositionParticipant = async ({ isFx, payload, determiningTransferChe // Only check transfers that have a related fxTransfer if (determiningTransferCheckResult?.watchListRecords?.length > 0) { const counterPartyParticipantFXPProxy = cyrilResult.participantName + console.log(counterPartyParticipantFXPProxy) + console.log(proxyObligation?.counterPartyFspProxyOrParticipantId?.proxyId) isSameProxy = counterPartyParticipantFXPProxy && proxyObligation?.counterPartyFspProxyOrParticipantId?.proxyId ? counterPartyParticipantFXPProxy === proxyObligation.counterPartyFspProxyOrParticipantId.proxyId : false @@ -356,14 +201,14 @@ const definePositionParticipant = async ({ isFx, payload, determiningTransferChe if (isSameProxy) { messageKey = '0' } else { + const participantName = cyrilResult.participantName const account = await Participant.getAccountByNameAndCurrency( - cyrilResult.participantName, + participantName, cyrilResult.currencyId, Enum.Accounts.LedgerAccountType.POSITION ) messageKey = account.participantCurrencyId.toString() } - logger.info('prepare positionParticipant details:', { messageKey, isSameProxy, cyrilResult }) return { messageKey, @@ -373,6 +218,7 @@ const definePositionParticipant = async ({ isFx, payload, determiningTransferChe const sendPositionPrepareMessage = async ({ isFx, + payload, action, params, determiningTransferCheckResult, @@ -472,14 +318,177 @@ const prepare = async (error, messages) => { } if (proxyEnabled && isForwarded) { - const isOk = await forwardPrepare({ isFx, params, ID }) - logger.info('forwardPrepare message is processed', { isOk, isFx, ID }) - return isOk + if (isFx) { + const fxTransfer = await FxTransferService.getByIdLight(ID) + if (!fxTransfer) { + const eventDetail = { + functionality: Enum.Events.Event.Type.NOTIFICATION, + action: Enum.Events.Event.Action.FX_FORWARDED + } + const fspiopError = ErrorHandler.Factory.createFSPIOPError( + ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, + 'Forwarded fxTransfer could not be found.' + ).toApiErrorObject(Config.ERROR_HANDLING) + // IMPORTANT: This singular message is taken by the ml-api-adapter and used to + // notify the payerFsp and proxy of the error. + // As long as the `to` and `from` message values are the fsp and fxp, + // and the action is `fx-forwarded`, the ml-api-adapter will notify both. + await Kafka.proceed( + Config.KAFKA_CONFIG, + params, + { + consumerCommit, + fspiopError, + eventDetail + } + ) + return true + } else { + if (fxTransfer.fxTransferState === Enum.Transfers.TransferInternalState.RESERVED) { + await FxTransferService.forwardedFxPrepare(ID) + } else { + const eventDetail = { + functionality: Enum.Events.Event.Type.NOTIFICATION, + action: Enum.Events.Event.Action.FX_FORWARDED + } + const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError( + `Invalid State: ${fxTransfer.fxTransferState} - expected: ${Enum.Transfers.TransferInternalState.RESERVED}` + ).toApiErrorObject(Config.ERROR_HANDLING) + // IMPORTANT: This singular message is taken by the ml-api-adapter and used to + // notify the payerFsp and proxy of the error. + // As long as the `to` and `from` message values are the fsp and fxp, + // and the action is `fx-forwarded`, the ml-api-adapter will notify both. + await Kafka.proceed( + Config.KAFKA_CONFIG, + params, + { + consumerCommit, + fspiopError, + eventDetail + } + ) + } + } + } else { + const transfer = await TransferService.getById(ID) + if (!transfer) { + const eventDetail = { + functionality: Enum.Events.Event.Type.NOTIFICATION, + action: Enum.Events.Event.Action.FORWARDED + } + const fspiopError = ErrorHandler.Factory.createFSPIOPError( + ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, + 'Forwarded transfer could not be found.' + ).toApiErrorObject(Config.ERROR_HANDLING) + // IMPORTANT: This singular message is taken by the ml-api-adapter and used to + // notify the payerFsp and proxy of the error. + // As long as the `to` and `from` message values are the payer and payee, + // and the action is `forwarded`, the ml-api-adapter will notify both. + await Kafka.proceed( + Config.KAFKA_CONFIG, + params, + { + consumerCommit, + fspiopError, + eventDetail + } + ) + return true + } + + if (transfer.transferState === Enum.Transfers.TransferInternalState.RESERVED) { + await TransferService.forwardedPrepare(ID) + } else { + const eventDetail = { + functionality: Enum.Events.Event.Type.NOTIFICATION, + action: Enum.Events.Event.Action.FORWARDED + } + const fspiopError = ErrorHandler.Factory.createInternalServerFSPIOPError( + `Invalid State: ${transfer.transferState} - expected: ${Enum.Transfers.TransferInternalState.RESERVED}` + ).toApiErrorObject(Config.ERROR_HANDLING) + // IMPORTANT: This singular message is taken by the ml-api-adapter and used to + // notify the payerFsp and proxy of the error. + // As long as the `to` and `from` message values are the payer and payee, + // and the action is `forwarded`, the ml-api-adapter will notify both. + await Kafka.proceed( + Config.KAFKA_CONFIG, + params, + { + consumerCommit, + fspiopError, + eventDetail + } + ) + } + } + return true } - const proxyObligation = await calculateProxyObligation({ - payload, isFx, params, functionality, action - }) + let initiatingFspProxyOrParticipantId + let counterPartyFspProxyOrParticipantId + const proxyObligation = { + isInitiatingFspProxy: false, + isCounterPartyFspProxy: false, + initiatingFspProxyOrParticipantId: null, + counterPartyFspProxyOrParticipantId: null, + isFx, + payloadClone: { ...payload } + } + if (proxyEnabled) { + const [initiatingFsp, counterPartyFsp] = isFx ? [payload.initiatingFsp, payload.counterPartyFsp] : [payload.payerFsp, payload.payeeFsp] + ;[proxyObligation.initiatingFspProxyOrParticipantId, proxyObligation.counterPartyFspProxyOrParticipantId] = await Promise.all([ + ProxyCache.getFSPProxy(initiatingFsp), + ProxyCache.getFSPProxy(counterPartyFsp) + ]) + logger.debug('Prepare proxy cache lookup results', { + initiatingFsp, + counterPartyFsp, + initiatingFspProxyOrParticipantId: proxyObligation.initiatingFspProxyOrParticipantId, + counterPartyFspProxyOrParticipantId: proxyObligation.counterPartyFspProxyOrParticipantId + }) + + proxyObligation.isInitiatingFspProxy = !proxyObligation.initiatingFspProxyOrParticipantId.inScheme && + proxyObligation.initiatingFspProxyOrParticipantId.proxyId !== null + proxyObligation.isCounterPartyFspProxy = !proxyObligation.counterPartyFspProxyOrParticipantId.inScheme && + proxyObligation.counterPartyFspProxyOrParticipantId.proxyId !== null + + if (isFx) { + proxyObligation.payloadClone.initiatingFsp = !proxyObligation.initiatingFspProxyOrParticipantId?.inScheme && + proxyObligation.initiatingFspProxyOrParticipantId?.proxyId + ? proxyObligation.initiatingFspProxyOrParticipantId.proxyId + : payload.initiatingFsp + proxyObligation.payloadClone.counterPartyFsp = !proxyObligation.counterPartyFspProxyOrParticipantId?.inScheme && + proxyObligation.counterPartyFspProxyOrParticipantId?.proxyId + ? proxyObligation.counterPartyFspProxyOrParticipantId.proxyId + : payload.counterPartyFsp + } else { + proxyObligation.payloadClone.payerFsp = !proxyObligation.initiatingFspProxyOrParticipantId?.inScheme && + proxyObligation.initiatingFspProxyOrParticipantId?.proxyId + ? proxyObligation.initiatingFspProxyOrParticipantId.proxyId + : payload.payerFsp + proxyObligation.payloadClone.payeeFsp = !proxyObligation.counterPartyFspProxyOrParticipantId?.inScheme && + proxyObligation.counterPartyFspProxyOrParticipantId?.proxyId + ? proxyObligation.counterPartyFspProxyOrParticipantId.proxyId + : payload.payeeFsp + } + + // If either debtor participant or creditor participant aren't in the scheme and have no proxy representative, then throw an error. + if ((proxyObligation.initiatingFspProxyOrParticipantId.inScheme === false && proxyObligation.initiatingFspProxyOrParticipantId.proxyId === null) || + (proxyObligation.counterPartyFspProxyOrParticipantId.inScheme === false && proxyObligation.counterPartyFspProxyOrParticipantId.proxyId === null)) { + const fspiopError = ErrorHandler.Factory.createFSPIOPError( + ErrorHandler.Enums.FSPIOPErrorCodes.ID_NOT_FOUND, + `Payer proxy or payee proxy not found: initiatingFsp: ${initiatingFspProxyOrParticipantId} counterPartyFsp: ${counterPartyFspProxyOrParticipantId}` + ).toApiErrorObject(Config.ERROR_HANDLING) + await Kafka.proceed(Config.KAFKA_CONFIG, params, { + consumerCommit, + fspiopError, + eventDetail: { functionality, action }, + fromSwitch, + hubName: Config.HUB_NAME + }) + throw fspiopError + } + } const duplication = await checkDuplication({ payload, isFx, ID, location }) if (duplication.hasDuplicateId) { @@ -490,8 +499,10 @@ const prepare = async (error, messages) => { return success } - const determiningTransferCheckResult = await createRemittanceEntity(isFx) - .checkIfDeterminingTransferExists(proxyObligation.payloadClone, proxyObligation) + const determiningTransferCheckResult = await createRemittanceEntity(isFx).checkIfDeterminingTransferExists( + proxyObligation.payloadClone, + proxyObligation + ) const { validationPassed, reasons } = await Validator.validatePrepare( payload, @@ -512,9 +523,8 @@ const prepare = async (error, messages) => { determiningTransferCheckResult, proxyObligation }) - if (!validationPassed) { - logger.warn(Util.breadcrumb(location, { path: 'validationFailed' })) + logger.error(Util.breadcrumb(location, { path: 'validationFailed' })) const fspiopError = createFSPIOPError(FSPIOPErrorCodes.VALIDATION_ERROR, reasons.toString()) await createRemittanceEntity(isFx) .logTransferError(ID, FSPIOPErrorCodes.VALIDATION_ERROR.code, reasons.toString()) @@ -536,7 +546,7 @@ const prepare = async (error, messages) => { logger.info(Util.breadcrumb(location, `positionTopic1--${actionLetter}7`)) const success = await sendPositionPrepareMessage({ - isFx, action, params, determiningTransferCheckResult, proxyObligation + isFx, payload, action, params, determiningTransferCheckResult, proxyObligation }) histTimerEnd({ success, fspId }) @@ -544,7 +554,8 @@ const prepare = async (error, messages) => { } catch (err) { histTimerEnd({ success: false, fspId }) const fspiopError = reformatFSPIOPError(err) - logger.error(`${Util.breadcrumb(location)}::${err.message}`, err) + logger.error(`${Util.breadcrumb(location)}::${err.message}--P0`) + logger.error(err.stack) const state = new EventSdk.EventStateMetadata(EventSdk.EventStatusType.failed, fspiopError.apiErrorCode.code, fspiopError.apiErrorCode.message) await span.error(fspiopError, state) await span.finish(fspiopError.message, state) @@ -558,8 +569,6 @@ const prepare = async (error, messages) => { module.exports = { prepare, - forwardPrepare, - calculateProxyObligation, checkDuplication, processDuplication, savePreparedRequest, diff --git a/src/lib/proxyCache.js b/src/lib/proxyCache.js index 2413220c1..21b4f6297 100644 --- a/src/lib/proxyCache.js +++ b/src/lib/proxyCache.js @@ -33,26 +33,12 @@ const getCache = () => { return proxyCache } -/** - * @typedef {Object} ProxyOrParticipant - An object containing the inScheme status, proxyId and FSP name - * @property {boolean} inScheme - Is FSP in the scheme. - * @property {string|null} proxyId - Proxy, associated with the FSP, if FSP is not in the scheme. - * @property {string} name - FSP name. - */ - -/** - * Checks if dfspId is in scheme or proxy. - * - * @param {string} dfspId - The DFSP ID to check. - * @returns {ProxyOrParticipant} proxyOrParticipant details - */ const getFSPProxy = async (dfspId) => { logger.debug('Checking if dfspId is in scheme or proxy', { dfspId }) const participant = await ParticipantService.getByName(dfspId) return { inScheme: !!participant, - proxyId: !participant ? await getCache().lookupProxyByDfspId(dfspId) : null, - name: dfspId + proxyId: !participant ? await getCache().lookupProxyByDfspId(dfspId) : null } } diff --git a/src/models/fxTransfer/fxTransfer.js b/src/models/fxTransfer/fxTransfer.js index a691ea7d6..0e542f1c1 100644 --- a/src/models/fxTransfer/fxTransfer.js +++ b/src/models/fxTransfer/fxTransfer.js @@ -6,10 +6,9 @@ const TransferEventAction = Enum.Events.Event.Action const Db = require('../../lib/db') const participant = require('../participant/facade') -const ParticipantCachedModel = require('../participant/participantCached') -const externalParticipantModel = require('../participant/externalParticipant') const { TABLE_NAMES } = require('../../shared/constants') const { logger } = require('../../shared/logger') +const ParticipantCachedModel = require('../participant/participantCached') const { TransferInternalState } = Enum.Transfers @@ -200,16 +199,6 @@ const getAllDetailsByCommitRequestIdForProxiedFxTransfer = async (commitRequestI const getParticipant = async (name, currency) => participant.getByNameAndCurrency(name, currency, Enum.Accounts.LedgerAccountType.POSITION) -/** - * Saves prepare fxTransfer details to DB. - * - * @param {Object} payload - Message payload. - * @param {string | null} stateReason - Validation failure reasons. - * @param {Boolean} hasPassedValidation - Is fxTransfer prepare validation passed. - * @param {DeterminingTransferCheckResult} determiningTransferCheckResult - Determining transfer check result. - * @param {ProxyObligation} proxyObligation - The proxy obligation - * @returns {Promise} - */ const savePreparedRequest = async ( payload, stateReason, @@ -225,10 +214,10 @@ const savePreparedRequest = async ( // Substitute out of scheme participants with their proxy representatives const initiatingFsp = proxyObligation.isInitiatingFspProxy - ? proxyObligation.initiatingFspProxyOrParticipantId.proxyId + ? proxyObligation.initiatingFspProxyOrParticipantId?.proxyId : payload.initiatingFsp const counterPartyFsp = proxyObligation.isCounterPartyFspProxy - ? proxyObligation.counterPartyFspProxyOrParticipantId.proxyId + ? proxyObligation.counterPartyFspProxyOrParticipantId?.proxyId : payload.counterPartyFsp // If creditor(counterPartyFsp) is a proxy in a jurisdictional scenario, @@ -268,10 +257,6 @@ const savePreparedRequest = async ( transferParticipantRoleTypeId: Enum.Accounts.TransferParticipantRoleType.INITIATING_FSP, ledgerEntryTypeId: Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE } - if (proxyObligation.isInitiatingFspProxy) { - initiatingParticipantRecord.externalParticipantId = await externalParticipantModel - .getIdByNameOrCreate(proxyObligation.initiatingFspProxyOrParticipantId) - } const counterPartyParticipantRecord1 = { commitRequestId: payload.commitRequestId, @@ -282,10 +267,6 @@ const savePreparedRequest = async ( fxParticipantCurrencyTypeId: Enum.Fx.FxParticipantCurrencyType.SOURCE, ledgerEntryTypeId: Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE } - if (proxyObligation.isCounterPartyFspProxy) { - counterPartyParticipantRecord1.externalParticipantId = await externalParticipantModel - .getIdByNameOrCreate(proxyObligation.counterPartyFspProxyOrParticipantId) - } let counterPartyParticipantRecord2 = null if (!proxyObligation.isCounterPartyFspProxy) { diff --git a/src/models/participant/externalParticipant.js b/src/models/participant/externalParticipant.js deleted file mode 100644 index 2215212de..000000000 --- a/src/models/participant/externalParticipant.js +++ /dev/null @@ -1,123 +0,0 @@ -/***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Eugen Klymniuk - -------------- - **********/ - -const ErrorHandler = require('@mojaloop/central-services-error-handling') -const Db = require('../../lib/db') -const { logger } = require('../../shared/logger') -const { TABLE_NAMES } = require('../../shared/constants') - -const TABLE = TABLE_NAMES.externalParticipant -const ID_FIELD = 'externalParticipantId' - -const log = logger.child(`DB#${TABLE}`) - -// todo: use caching lib -const CACHE = {} -const cache = { - get (key) { - return CACHE[key] - }, - set (key, value) { - CACHE[key] = value - } -} - -const create = async ({ name, proxyId }) => { - try { - const result = await Db.from(TABLE).insert({ name, proxyId }) - log.debug('create result:', { result }) - return result - } catch (err) { - log.error('error in create', err) - throw ErrorHandler.Factory.reformatFSPIOPError(err) - } -} - -const getOneBy = async (criteria, options) => { - try { - const result = await Db.from(TABLE).findOne(criteria, options) - log.debug('getOneBy result:', { criteria, result }) - return result - } catch (err) { - log.error('error in getOneBy:', err) - throw ErrorHandler.Factory.reformatFSPIOPError(err) - } -} -const getOneById = async (id, options) => getOneBy({ [ID_FIELD]: id }, options) -const getOneByName = async (name, options) => getOneBy({ name }, options) - -const getOneByNameCached = async (name, options = {}) => { - let data = cache.get(name) - if (data) { - log.debug('getOneByIdCached cache hit:', { name, data }) - } else { - data = await getOneByName(name, options) - cache.set(name, data) - log.debug('getOneByIdCached cache updated:', { name, data }) - } - return data -} - -const getIdByNameOrCreate = async ({ name, proxyId }) => { - try { - let dfsp = await getOneByNameCached(name) - if (!dfsp) { - await create({ name, proxyId }) - // todo: check if create returns id (to avoid getOneByNameCached call) - dfsp = await getOneByNameCached(name) - } - const id = dfsp?.[ID_FIELD] - log.verbose('getIdByNameOrCreate result:', { id, name }) - return id - } catch (err) { - log.child({ name, proxyId }).warn('error in getIdByNameOrCreate:', err) - return null - // todo: think, if we need to rethrow an error here? - } -} - -const destroyBy = async (criteria) => { - try { - const result = await Db.from(TABLE).destroy(criteria) - log.debug('destroyBy result:', { criteria, result }) - return result - } catch (err) { - log.error('error in destroyBy', err) - throw ErrorHandler.Factory.reformatFSPIOPError(err) - } -} -const destroyById = async (id) => destroyBy({ [ID_FIELD]: id }) -const destroyByName = async (name) => destroyBy({ name }) - -// todo: think, if we need update method -module.exports = { - create, - getIdByNameOrCreate, - getOneByNameCached, - getOneByName, - getOneById, - destroyById, - destroyByName -} diff --git a/src/models/transfer/facade.js b/src/models/transfer/facade.js index 8b12e32ca..191f90aa0 100644 --- a/src/models/transfer/facade.js +++ b/src/models/transfer/facade.js @@ -33,22 +33,19 @@ * @module src/models/transfer/facade/ */ -const ErrorHandler = require('@mojaloop/central-services-error-handling') -const Metrics = require('@mojaloop/central-services-metrics') -const MLNumber = require('@mojaloop/ml-number') -const Enum = require('@mojaloop/central-services-shared').Enum -const Time = require('@mojaloop/central-services-shared').Util.Time - -const { logger } = require('../../shared/logger') const Db = require('../../lib/db') -const Config = require('../../lib/config') -const ParticipantFacade = require('../participant/facade') -const ParticipantCachedModel = require('../participant/participantCached') -const externalParticipantModel = require('../participant/externalParticipant') -const TransferExtensionModel = require('./transferExtension') - +const Enum = require('@mojaloop/central-services-shared').Enum const TransferEventAction = Enum.Events.Event.Action const TransferInternalState = Enum.Transfers.TransferInternalState +const TransferExtensionModel = require('./transferExtension') +const ParticipantFacade = require('../participant/facade') +const ParticipantCachedModel = require('../participant/participantCached') +const Time = require('@mojaloop/central-services-shared').Util.Time +const MLNumber = require('@mojaloop/ml-number') +const Config = require('../../lib/config') +const ErrorHandler = require('@mojaloop/central-services-error-handling') +const Logger = require('@mojaloop/central-services-logger') +const Metrics = require('@mojaloop/central-services-metrics') // Alphabetically ordered list of error texts used below const UnsupportedActionText = 'Unsupported action' @@ -359,12 +356,12 @@ const savePayeeTransferResponse = async (transferId, payload, action, fspiopErro .orderBy('changedDate', 'desc') }) transferFulfilmentRecord.settlementWindowId = res[0].settlementWindowId - logger.debug('savePayeeTransferResponse::settlementWindowId') + Logger.isDebugEnabled && Logger.debug('savePayeeTransferResponse::settlementWindowId') } if (isFulfilment) { await knex('transferFulfilment').transacting(trx).insert(transferFulfilmentRecord) result.transferFulfilmentRecord = transferFulfilmentRecord - logger.debug('savePayeeTransferResponse::transferFulfilment') + Logger.isDebugEnabled && Logger.debug('savePayeeTransferResponse::transferFulfilment') } if (transferExtensionRecordsList.length > 0) { // ###! CAN BE DONE THROUGH A BATCH @@ -373,11 +370,11 @@ const savePayeeTransferResponse = async (transferId, payload, action, fspiopErro } // ###! result.transferExtensionRecordsList = transferExtensionRecordsList - logger.debug('savePayeeTransferResponse::transferExtensionRecordsList') + Logger.isDebugEnabled && Logger.debug('savePayeeTransferResponse::transferExtensionRecordsList') } await knex('transferStateChange').transacting(trx).insert(transferStateChangeRecord) result.transferStateChangeRecord = transferStateChangeRecord - logger.debug('savePayeeTransferResponse::transferStateChange') + Logger.isDebugEnabled && Logger.debug('savePayeeTransferResponse::transferStateChange') if (fspiopError) { const insertedTransferStateChange = await knex('transferStateChange').transacting(trx) .where({ transferId }) @@ -386,14 +383,14 @@ const savePayeeTransferResponse = async (transferId, payload, action, fspiopErro transferErrorRecord.transferStateChangeId = insertedTransferStateChange.transferStateChangeId await knex('transferError').transacting(trx).insert(transferErrorRecord) result.transferErrorRecord = transferErrorRecord - logger.debug('savePayeeTransferResponse::transferError') + Logger.isDebugEnabled && Logger.debug('savePayeeTransferResponse::transferError') } histTPayeeResponseValidationPassedEnd({ success: true, queryName: 'facade_saveTransferPrepared_transaction' }) result.savePayeeTransferResponseExecuted = true - logger.debug('savePayeeTransferResponse::success') + Logger.isDebugEnabled && Logger.debug('savePayeeTransferResponse::success') } catch (err) { - logger.error('savePayeeTransferResponse::failure', err) histTPayeeResponseValidationPassedEnd({ success: false, queryName: 'facade_saveTransferPrepared_transaction' }) + Logger.isErrorEnabled && Logger.error('savePayeeTransferResponse::failure') throw err } }) @@ -405,16 +402,6 @@ const savePayeeTransferResponse = async (transferId, payload, action, fspiopErro } } -/** - * Saves prepare transfer details to DB. - * - * @param {Object} payload - Message payload. - * @param {string | null} stateReason - Validation failure reasons. - * @param {Boolean} hasPassedValidation - Is transfer prepare validation passed. - * @param {DeterminingTransferCheckResult} determiningTransferCheckResult - Determining transfer check result. - * @param {ProxyObligation} proxyObligation - The proxy obligation - * @returns {Promise} - */ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValidation = true, determiningTransferCheckResult, proxyObligation) => { const histTimerSaveTransferPreparedEnd = Metrics.getHistogram( 'model_transfer', @@ -428,7 +415,8 @@ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValida } // Iterate over the participants and get the details - for (const name of Object.keys(participants)) { + const names = Object.keys(participants) + for (const name of names) { const participant = await ParticipantCachedModel.getByName(name) if (participant) { participants[name].id = participant.participantId @@ -439,26 +427,26 @@ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValida const participantCurrencyRecord = await ParticipantFacade.getByNameAndCurrency(participantCurrency.participantName, participantCurrency.currencyId, Enum.Accounts.LedgerAccountType.POSITION) participants[name].participantCurrencyId = participantCurrencyRecord?.participantCurrencyId } - } - if (proxyObligation?.isInitiatingFspProxy) { - const proxyId = proxyObligation.initiatingFspProxyOrParticipantId.proxyId - const proxyParticipant = await ParticipantCachedModel.getByName(proxyId) - participants[proxyId] = {} - participants[proxyId].id = proxyParticipant.participantId - const participantCurrencyRecord = await ParticipantFacade.getByNameAndCurrency( - proxyId, payload.amount.currency, Enum.Accounts.LedgerAccountType.POSITION - ) - // In a regional scheme, the stand-in initiating FSP proxy may not have a participantCurrencyId - // of the target currency of the transfer, so set to null if not found - participants[proxyId].participantCurrencyId = participantCurrencyRecord?.participantCurrencyId - } + if (proxyObligation?.isInitiatingFspProxy) { + const proxyId = proxyObligation.initiatingFspProxyOrParticipantId.proxyId + const proxyParticipant = await ParticipantCachedModel.getByName(proxyId) + participants[proxyId] = {} + participants[proxyId].id = proxyParticipant.participantId + const participantCurrencyRecord = await ParticipantFacade.getByNameAndCurrency( + proxyId, payload.amount.currency, Enum.Accounts.LedgerAccountType.POSITION + ) + // In a regional scheme, the stand-in initiating FSP proxy may not have a participantCurrencyId + // of the target currency of the transfer, so set to null if not found + participants[proxyId].participantCurrencyId = participantCurrencyRecord?.participantCurrencyId + } - if (proxyObligation?.isCounterPartyFspProxy) { - const proxyId = proxyObligation.counterPartyFspProxyOrParticipantId.proxyId - const proxyParticipant = await ParticipantCachedModel.getByName(proxyId) - participants[proxyId] = {} - participants[proxyId].id = proxyParticipant.participantId + if (proxyObligation?.isCounterPartyFspProxy) { + const proxyId = proxyObligation.counterPartyFspProxyOrParticipantId.proxyId + const proxyParticipant = await ParticipantCachedModel.getByName(proxyId) + participants[proxyId] = {} + participants[proxyId].id = proxyParticipant.participantId + } } const transferRecord = { @@ -474,25 +462,24 @@ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValida value: payload.ilpPacket } + const state = ((hasPassedValidation) ? Enum.Transfers.TransferInternalState.RECEIVED_PREPARE : Enum.Transfers.TransferInternalState.INVALID) + const transferStateChangeRecord = { transferId: payload.transferId, - transferStateId: hasPassedValidation ? TransferInternalState.RECEIVED_PREPARE : TransferInternalState.INVALID, + transferStateId: state, reason: stateReason, createdDate: Time.getUTCString(new Date()) } let payerTransferParticipantRecord if (proxyObligation?.isInitiatingFspProxy) { - const externalParticipantId = await externalParticipantModel.getIdByNameOrCreate(proxyObligation.initiatingFspProxyOrParticipantId) - // todo: think, what if externalParticipantId is null? payerTransferParticipantRecord = { transferId: payload.transferId, participantId: participants[proxyObligation.initiatingFspProxyOrParticipantId.proxyId].id, participantCurrencyId: participants[proxyObligation.initiatingFspProxyOrParticipantId.proxyId].participantCurrencyId, transferParticipantRoleTypeId: Enum.Accounts.TransferParticipantRoleType.PAYER_DFSP, ledgerEntryTypeId: Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE, - amount: -payload.amount.amount, - externalParticipantId + amount: -payload.amount.amount } } else { payerTransferParticipantRecord = { @@ -505,19 +492,16 @@ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValida } } - logger.debug('saveTransferPrepared participants:', { participants }) + console.log(participants) let payeeTransferParticipantRecord if (proxyObligation?.isCounterPartyFspProxy) { - const externalParticipantId = await externalParticipantModel.getIdByNameOrCreate(proxyObligation.counterPartyFspProxyOrParticipantId) - // todo: think, what if externalParticipantId is null? payeeTransferParticipantRecord = { transferId: payload.transferId, participantId: participants[proxyObligation.counterPartyFspProxyOrParticipantId.proxyId].id, participantCurrencyId: null, transferParticipantRoleTypeId: Enum.Accounts.TransferParticipantRoleType.PAYEE_DFSP, ledgerEntryTypeId: Enum.Accounts.LedgerEntryType.PRINCIPLE_VALUE, - amount: -payload.amount.amount, - externalParticipantId + amount: -payload.amount.amount } } else { payeeTransferParticipantRecord = { @@ -573,14 +557,14 @@ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValida try { await knex('transferParticipant').insert(payerTransferParticipantRecord) } catch (err) { - logger.warn('Payer transferParticipant insert error', err) + Logger.isWarnEnabled && Logger.warn(`Payer transferParticipant insert error: ${err.message}`) histTimerSaveTranferNoValidationEnd({ success: false, queryName: 'facade_saveTransferPrepared_no_validation' }) } try { await knex('transferParticipant').insert(payeeTransferParticipantRecord) } catch (err) { - logger.warn('Payee transferParticipant insert error:', err) histTimerSaveTranferNoValidationEnd({ success: false, queryName: 'facade_saveTransferPrepared_no_validation' }) + Logger.isWarnEnabled && Logger.warn(`Payee transferParticipant insert error: ${err.message}`) } payerTransferParticipantRecord.name = payload.payerFsp payeeTransferParticipantRecord.name = payload.payeeFsp @@ -596,21 +580,21 @@ const saveTransferPrepared = async (payload, stateReason = null, hasPassedValida try { await knex.batchInsert('transferExtension', transferExtensionsRecordList) } catch (err) { - logger.warn('batchInsert transferExtension error:', err) + Logger.isWarnEnabled && Logger.warn(`batchInsert transferExtension error: ${err.message}`) histTimerSaveTranferNoValidationEnd({ success: false, queryName: 'facade_saveTransferPrepared_no_validation' }) } } try { await knex('ilpPacket').insert(ilpPacketRecord) } catch (err) { - logger.warn('ilpPacket insert error:', err) + Logger.isWarnEnabled && Logger.warn(`ilpPacket insert error: ${err.message}`) histTimerSaveTranferNoValidationEnd({ success: false, queryName: 'facade_saveTransferPrepared_no_validation' }) } try { await knex('transferStateChange').insert(transferStateChangeRecord) histTimerSaveTranferNoValidationEnd({ success: true, queryName: 'facade_saveTransferPrepared_no_validation' }) } catch (err) { - logger.warn('transferStateChange insert error:', err) + Logger.isWarnEnabled && Logger.warn(`transferStateChange insert error: ${err.message}`) histTimerSaveTranferNoValidationEnd({ success: false, queryName: 'facade_saveTransferPrepared_no_validation' }) } } @@ -1437,7 +1421,7 @@ const recordFundsIn = async (payload, transactionTimestamp, enums) => { await TransferFacade.reconciliationTransferReserve(payload, transactionTimestamp, enums, trx) await TransferFacade.reconciliationTransferCommit(payload, transactionTimestamp, enums, trx) } catch (err) { - logger.error('error in recordFundsIn:', err) + Logger.isErrorEnabled && Logger.error(err) throw ErrorHandler.Factory.reformatFSPIOPError(err) } }) diff --git a/src/shared/constants.js b/src/shared/constants.js index 91e90f501..5fdd7165e 100644 --- a/src/shared/constants.js +++ b/src/shared/constants.js @@ -1,7 +1,6 @@ const { Enum } = require('@mojaloop/central-services-shared') const TABLE_NAMES = Object.freeze({ - externalParticipant: 'externalParticipant', fxTransfer: 'fxTransfer', fxTransferDuplicateCheck: 'fxTransferDuplicateCheck', fxTransferErrorDuplicateCheck: 'fxTransferErrorDuplicateCheck', diff --git a/test/fixtures.js b/test/fixtures.js index a0e93007a..15974730d 100644 --- a/test/fixtures.js +++ b/test/fixtures.js @@ -299,18 +299,6 @@ const watchListItemDto = ({ createdDate }) -const mockExternalParticipantDto = ({ - name = `extFsp-${Date.now()}`, - proxyId = `proxy-${Date.now()}`, - id = Date.now(), - createdDate = new Date() -} = {}) => ({ - name, - proxyId, - ...(id && { externalParticipantId: id }), - ...(createdDate && { createdDate }) -}) - module.exports = { ILP_PACKET, CONDITION, @@ -336,6 +324,5 @@ module.exports = { fxTransferDto, fxFulfilResponseDto, fxtGetAllDetailsByCommitRequestIdDto, - watchListItemDto, - mockExternalParticipantDto + watchListItemDto } diff --git a/test/unit/lib/proxyCache.test.js b/test/unit/lib/proxyCache.test.js index ab8407760..4104b7570 100644 --- a/test/unit/lib/proxyCache.test.js +++ b/test/unit/lib/proxyCache.test.js @@ -86,19 +86,17 @@ Test('Proxy Cache test', async (proxyCacheTest) => { await proxyCacheTest.test('getFSPProxy', async (getFSPProxyTest) => { await getFSPProxyTest.test('resolve proxy id if participant not in scheme and proxyId is in cache', async (test) => { ParticipantService.getByName.returns(Promise.resolve(null)) - const dfspId = 'existingDfspId1' - const result = await ProxyCache.getFSPProxy(dfspId) + const result = await ProxyCache.getFSPProxy('existingDfspId1') - test.deepEqual(result, { inScheme: false, proxyId: 'proxyId', name: dfspId }) + test.deepEqual(result, { inScheme: false, proxyId: 'proxyId' }) test.end() }) await getFSPProxyTest.test('resolve proxy id if participant not in scheme and proxyId is not cache', async (test) => { ParticipantService.getByName.returns(Promise.resolve(null)) - const dsfpId = 'nonExistingDfspId1' - const result = await ProxyCache.getFSPProxy(dsfpId) + const result = await ProxyCache.getFSPProxy('nonExistingDfspId1') - test.deepEqual(result, { inScheme: false, proxyId: null, name: dsfpId }) + test.deepEqual(result, { inScheme: false, proxyId: null }) test.end() }) @@ -106,7 +104,7 @@ Test('Proxy Cache test', async (proxyCacheTest) => { ParticipantService.getByName.returns(Promise.resolve({ participantId: 1 })) const result = await ProxyCache.getFSPProxy('existingDfspId1') - test.deepEqual(result, { inScheme: true, proxyId: null, name: 'existingDfspId1' }) + test.deepEqual(result, { inScheme: true, proxyId: null }) test.end() }) diff --git a/test/unit/models/participant/externalParticipant.test.js b/test/unit/models/participant/externalParticipant.test.js deleted file mode 100644 index 8ba7dfb4b..000000000 --- a/test/unit/models/participant/externalParticipant.test.js +++ /dev/null @@ -1,135 +0,0 @@ -/***** - License - -------------- - Copyright © 2017 Bill & Melinda Gates Foundation - The Mojaloop files are made available by the Bill & Melinda Gates Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - - Contributors - -------------- - This is the official list of the Mojaloop project contributors for this file. - Names of the original copyright holders (individuals or organizations) - should be listed with a '*' in the first column. People who have - contributed from an organization can be listed under the organization - that actually holds the copyright for their contributions (see the - Gates Foundation organization for an example). Those individuals should have - their names indented and be marked with a '-'. Email address can be added - optionally within square brackets . - * Gates Foundation - - Name Surname - - * Eugen Klymniuk - -------------- - **********/ -process.env.LOG_LEVEL = 'debug' - -const Test = require('tapes')(require('tape')) -const Sinon = require('sinon') -const model = require('#src/models/participant/externalParticipant') -const Db = require('#src/lib/db') -const { TABLE_NAMES } = require('#src/shared/constants') - -const { tryCatchEndTest } = require('#test/util/helpers') -const { mockExternalParticipantDto } = require('#test/fixtures') - -const EP_TABLE = TABLE_NAMES.externalParticipant - -Test('externalParticipant Model Tests -->', (epmTest) => { - let sandbox - - epmTest.beforeEach(t => { - sandbox = Sinon.createSandbox() - - const dbStub = sandbox.stub(Db) - Db.from = table => dbStub[table] - Db[EP_TABLE] = { - insert: sandbox.stub(), - findOne: sandbox.stub(), - destroy: sandbox.stub() - } - t.end() - }) - - epmTest.afterEach(t => { - sandbox.restore() - t.end() - }) - - epmTest.test('should create externalParticipant in DB', tryCatchEndTest(async (t) => { - const data = mockExternalParticipantDto({ id: null, createdDate: null }) - Db[EP_TABLE].insert.withArgs(data).resolves(true) - const result = await model.create(data) - t.ok(result) - })) - - epmTest.test('should get externalParticipant by name from DB', tryCatchEndTest(async (t) => { - const data = mockExternalParticipantDto() - Db[EP_TABLE].findOne.withArgs({ name: data.name }).resolves(data) - const result = await model.getOneByName(data.name) - t.deepEqual(result, data) - })) - - epmTest.test('should get externalParticipant by name from cache', tryCatchEndTest(async (t) => { - const name = `extFsp-${Date.now()}` - const data = mockExternalParticipantDto({ name }) - Db[EP_TABLE].findOne.withArgs({ name }).resolves(data) - const result = await model.getOneByNameCached(name) - t.deepEqual(result, data) - - Db[EP_TABLE].findOne = sandbox.stub() - const cached = await model.getOneByNameCached(name) - t.deepEqual(cached, data, 'cached externalParticipant') - t.ok(Db[EP_TABLE].findOne.notCalled, 'db.findOne is called') - })) - - epmTest.test('should get externalParticipant ID from db (no data in cache)', tryCatchEndTest(async (t) => { - const name = `extFsp-${Date.now()}` - const data = mockExternalParticipantDto({ name }) - Db[EP_TABLE].findOne.withArgs({ name }).resolves(data) - - const id = await model.getIdByNameOrCreate({ name }) - t.equal(id, data.externalParticipantId) - })) - - epmTest.test('should create externalParticipant, and get its id from db (if no data in db)', tryCatchEndTest(async (t) => { - const data = mockExternalParticipantDto() - const { name, proxyId } = data - const fspList = [] - Db[EP_TABLE].findOne = async json => (json.name === name && fspList[0]) - Db[EP_TABLE].insert = async json => { if (json.name === name && json.proxyId === proxyId) fspList.push(data) } - - const id = await model.getIdByNameOrCreate({ name, proxyId }) - t.equal(id, data.externalParticipantId) - })) - - epmTest.test('should return null in case of error inside getIdByNameOrCreate method', tryCatchEndTest(async (t) => { - Db[EP_TABLE].findOne.rejects(new Error('DB error')) - const id = await model.getIdByNameOrCreate(mockExternalParticipantDto()) - t.equal(id, null) - })) - - epmTest.test('should get externalParticipant by id', tryCatchEndTest(async (t) => { - const id = 'id123' - const data = { name: 'extFsp', proxyId: '123' } - Db[EP_TABLE].findOne.withArgs({ externalParticipantId: id }).resolves(data) - const result = await model.getOneById(id) - t.deepEqual(result, data) - })) - - epmTest.test('should delete externalParticipant record by name', tryCatchEndTest(async (t) => { - const name = 'extFsp' - Db[EP_TABLE].destroy.withArgs({ name }).resolves(true) - const result = await model.destroyByName(name) - t.ok(result) - })) - - epmTest.test('should delete externalParticipant record by id', tryCatchEndTest(async (t) => { - const id = 123 - Db[EP_TABLE].destroy.withArgs({ externalParticipantId: id }).resolves(true) - const result = await model.destroyById(id) - t.ok(result) - })) - - epmTest.end() -}) diff --git a/test/util/helpers.js b/test/util/helpers.js index 19ebcc99d..fec192a35 100644 --- a/test/util/helpers.js +++ b/test/util/helpers.js @@ -27,7 +27,6 @@ const { FSPIOPError } = require('@mojaloop/central-services-error-handling').Factory const Logger = require('@mojaloop/central-services-logger') const Config = require('#src/lib/config') -const { logger } = require('#src/shared/logger/index') /* Helper Functions */ @@ -179,17 +178,6 @@ const checkErrorPayload = test => (actualPayload, expectedFspiopError) => { test.equal(actualPayload.errorInformation?.errorDescription, errorDescription, 'errorDescription matches') } -// to use as a wrapper on Tape tests -const tryCatchEndTest = (testFn) => async (t) => { - try { - await testFn(t) - } catch (err) { - logger.error(`error in test: "${t.name}"`, err) - t.fail(t.name) - } - t.end() -} - module.exports = { checkErrorPayload, currentEventLoopEnd, @@ -198,6 +186,5 @@ module.exports = { unwrapResponse, waitFor, wrapWithRetries, - getMessagePayloadOrThrow, - tryCatchEndTest + getMessagePayloadOrThrow }