diff --git a/audit-ci.jsonc b/audit-ci.jsonc index 01f799687..cad1ae8c2 100644 --- a/audit-ci.jsonc +++ b/audit-ci.jsonc @@ -10,6 +10,7 @@ "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-mg85-8mv5-ffjr", // https://github.com/advisories/GHSA-mg85-8mv5-ffjr + "GHSA-8hc4-vh64-cxmj" // https://github.com/advisories/GHSA-8hc4-vh64-cxmj ] } diff --git a/migrations/950109_fxQuote.js b/migrations/950109_fxQuote.js new file mode 100644 index 000000000..30371cd6b --- /dev/null +++ b/migrations/950109_fxQuote.js @@ -0,0 +1,20 @@ +// Notes: these changes are required for the quoting-service and are not used by central-ledger +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuote').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuote', (t) => { + t.string('conversionRequestId', 36).primary().notNullable() + + // time keeping + t.dateTime('expirationDate').defaultTo(null).nullable().comment('Optional expiration for the requested transaction') + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxQuote') +} diff --git a/migrations/950110_fxQuoteResponse.js b/migrations/950110_fxQuoteResponse.js new file mode 100644 index 000000000..755afc2bd --- /dev/null +++ b/migrations/950110_fxQuoteResponse.js @@ -0,0 +1,26 @@ +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuoteResponse').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuoteResponse', (t) => { + t.bigIncrements('fxQuoteResponseId').primary().notNullable() + + // reference to the original fxQuote + t.string('conversionRequestId', 36).notNullable() + t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote') + + // ilpCondition sent in FXP response + t.string('ilpCondition', 256).notNullable() + + // time keeping + t.dateTime('expirationDate').defaultTo(null).nullable().comment('Optional expiration for the requested transaction') + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxQuoteResponse') +} diff --git a/migrations/950111_fxQuoteError.js b/migrations/950111_fxQuoteError.js new file mode 100644 index 000000000..4fdee71ee --- /dev/null +++ b/migrations/950111_fxQuoteError.js @@ -0,0 +1,23 @@ +// Notes: these changes are required for the quoting-service and are not used by central-ledger +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuoteError').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuoteError', (t) => { + t.bigIncrements('fxQuoteErrorId').primary().notNullable() + t.string('conversionRequestId', 36).notNullable() + t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote') + t.bigInteger('fxQuoteResponseId').unsigned().defaultTo(null).nullable().comment('The response to the initial fxQuote') + t.foreign('fxQuoteResponseId').references('fxQuoteResponseId').inTable('fxQuoteResponse') + t.integer('errorCode').unsigned().notNullable() + t.string('errorDescription', 128).notNullable() + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable() + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('quoteError') +} diff --git a/migrations/950113_fxQuoteDuplicateCheck.js b/migrations/950113_fxQuoteDuplicateCheck.js new file mode 100644 index 000000000..c0e13e1ea --- /dev/null +++ b/migrations/950113_fxQuoteDuplicateCheck.js @@ -0,0 +1,18 @@ +// Notes: these changes are required for the quoting-service and are not used by central-ledger +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuoteDuplicateCheck').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuoteDuplicateCheck', (t) => { + t.string('conversionRequestId', 36).primary().notNullable() + t.string('hash', 1024).defaultTo(null).nullable().comment('hash value received for the quote request') + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxQuoteDuplicateCheck') +} diff --git a/migrations/950114_fxQuoteResponseDuplicateCheck.js b/migrations/950114_fxQuoteResponseDuplicateCheck.js new file mode 100644 index 000000000..8f60e1674 --- /dev/null +++ b/migrations/950114_fxQuoteResponseDuplicateCheck.js @@ -0,0 +1,21 @@ +// Notes: these changes are required for the quoting-service and are not used by central-ledger +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuoteResponseDuplicateCheck').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuoteResponseDuplicateCheck', (t) => { + t.bigIncrements('fxQuoteResponseId').primary().unsigned().comment('The response to the initial quote') + t.foreign('fxQuoteResponseId').references('fxQuoteResponseId').inTable('fxQuoteResponse') + t.string('conversionRequestId', 36).notNullable() + t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote') + t.string('hash', 255).defaultTo(null).nullable().comment('hash value received for the quote response') + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxQuoteResponseDuplicateCheck') +} diff --git a/migrations/950115_fxQuoteConversionTerms.js b/migrations/950115_fxQuoteConversionTerms.js new file mode 100644 index 000000000..e3743f913 --- /dev/null +++ b/migrations/950115_fxQuoteConversionTerms.js @@ -0,0 +1,33 @@ +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuoteConversionTerms').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuoteConversionTerms', (t) => { + t.string('conversionId').primary().notNullable() + + // reference to the original fxQuote + t.string('conversionRequestId', 36).notNullable() + t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote') + + t.integer('amountTypeId').unsigned().notNullable().comment('This is part of the transaction type that contains valid elements for - Amount Type') + t.foreign('amountTypeId').references('amountTypeId').inTable('amountType') + t.string('initiatingFsp', 255) + t.string('counterPartyFsp', 255) + t.decimal('sourceAmount', 18, 4).notNullable() + t.string('sourceCurrency', 3).notNullable() + t.foreign('sourceCurrency').references('currencyId').inTable('currency') + t.decimal('targetAmount', 18, 4).notNullable() + t.string('targetCurrency', 3).notNullable() + t.foreign('targetCurrency').references('currencyId').inTable('currency') + + // time keeping + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxQuoteConversionTerms') +} diff --git a/migrations/950116_fxQuoteConversionTermExtension.js b/migrations/950116_fxQuoteConversionTermExtension.js new file mode 100644 index 000000000..936a0af76 --- /dev/null +++ b/migrations/950116_fxQuoteConversionTermExtension.js @@ -0,0 +1,21 @@ +// Notes: these changes are required for the quoting-service and are not used by central-ledger +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuoteConversionTermExtension').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuoteConversionTermExtension', (t) => { + t.bigIncrements('fxQuoteConversionTermExtension').primary().notNullable() + t.string('conversionId', 36).notNullable() + t.foreign('conversionId').references('conversionId').inTable('fxQuoteConversionTerms') + t.string('key', 128).notNullable() + t.text('value').notNullable() + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxQuoteConversionTermExtension') +} diff --git a/migrations/950117_fxQuoteResponseConversionTerms.js b/migrations/950117_fxQuoteResponseConversionTerms.js new file mode 100644 index 000000000..c5dbbb3e0 --- /dev/null +++ b/migrations/950117_fxQuoteResponseConversionTerms.js @@ -0,0 +1,37 @@ +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuoteResponseConversionTerms').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuoteResponseConversionTerms', (t) => { + t.string('conversionId').primary().notNullable() + + // reference to the original fxQuote + t.string('conversionRequestId', 36).notNullable() + t.foreign('conversionRequestId').references('conversionRequestId').inTable('fxQuote') + + // reference to the original fxQuoteResponse + t.bigIncrements('fxQuoteResponseId', 36).notNullable() + t.foreign('fxQuoteResponseId').references('fxQuoteResponseId').inTable('fxQuoteResponse') + + t.integer('amountTypeId').unsigned().notNullable().comment('This is part of the transaction type that contains valid elements for - Amount Type') + t.foreign('amountTypeId').references('amountTypeId').inTable('amountType') + t.string('initiatingFsp', 255) + t.string('counterPartyFsp', 255) + t.decimal('sourceAmount', 18, 4).notNullable() + t.string('sourceCurrency', 3).notNullable() + t.foreign('sourceCurrency').references('currencyId').inTable('currency') + t.decimal('targetAmount', 18, 4).notNullable() + t.string('targetCurrency', 3).notNullable() + t.foreign('targetCurrency').references('currencyId').inTable('currency') + + // time keeping + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxQuoteResponseConversionTerms') +} diff --git a/migrations/950118_fxQuoteResponseConversionTermExtension.js b/migrations/950118_fxQuoteResponseConversionTermExtension.js new file mode 100644 index 000000000..d82b8056a --- /dev/null +++ b/migrations/950118_fxQuoteResponseConversionTermExtension.js @@ -0,0 +1,21 @@ +// Notes: these changes are required for the quoting-service and are not used by central-ledger +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxQuoteResponseConversionTermExtension').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxQuoteResponseConversionTermExtension', (t) => { + t.bigIncrements('fxQuoteResponseConversionTermExtension').primary().notNullable() + t.string('conversionId', 36).notNullable() + t.foreign('conversionId').references('conversionId').inTable('fxQuoteResponseConversionTerms') + t.string('key', 128).notNullable() + t.text('value').notNullable() + t.dateTime('createdDate').defaultTo(knex.fn.now()).notNullable().comment('System dateTime stamp pertaining to the inserted record') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxQuoteResponseConversionTermExtension') +} diff --git a/migrations/950119_fxCharge.js b/migrations/950119_fxCharge.js new file mode 100644 index 000000000..51f10be25 --- /dev/null +++ b/migrations/950119_fxCharge.js @@ -0,0 +1,27 @@ +'use strict' + +exports.up = (knex) => { + return knex.schema.hasTable('fxCharge').then((exists) => { + if (!exists) { + return knex.schema.createTable('fxCharge', (t) => { + t.bigIncrements('fxChargeId').primary().notNullable() + t.string('chargeType', 32).notNullable().comment('A description of the charge which is being levied.') + + // fxCharge should only be sent back in the response to an fxQuote + // so reference the terms in fxQuoteResponse `conversionTerms` + t.string('conversionId', 36).notNullable() + t.foreign('conversionId').references('conversionId').inTable('fxQuoteResponseConversionTerms') + + t.decimal('sourceAmount', 18, 4).nullable().comment('The amount of the charge which is being levied, expressed in the source currency.') + t.string('sourceCurrency', 3).nullable().comment('The currency in which the source amount charge is being levied.') + + t.decimal('targetAmount', 18, 4).nullable().comment('The amount of the charge which is being levied, expressed in the target currency.') + t.string('targetCurrency', 3).nullable().comment('The currency in which the target amount charge is being levied.') + }) + } + }) +} + +exports.down = (knex) => { + return knex.schema.dropTableIfExists('fxCharge') +} diff --git a/package-lock.json b/package-lock.json index 4365a22e1..a8bb63760 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "glob": "10.4.3", "hapi-auth-basic": "5.0.0", "hapi-auth-bearer-token": "8.0.0", - "hapi-swagger": "17.2.1", + "hapi-swagger": "17.3.0", "ilp-packet": "2.2.0", "knex": "3.1.0", "lodash": "4.17.21", @@ -58,7 +58,7 @@ "jsdoc": "4.0.3", "jsonpath": "1.1.1", "nodemon": "3.1.4", - "npm-check-updates": "17.0.3", + "npm-check-updates": "17.0.6", "nyc": "17.0.0", "pre-commit": "1.2.2", "proxyquire": "2.1.3", @@ -98,9 +98,9 @@ } }, "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.6.2", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.2.tgz", - "integrity": "sha512-ENUdLLT04aDbbHCRwfKf8gR67AhV0CdFrOAtk+FcakBAgaq6ds3HLK9X0BCyiFUz8pK9uP+k6YZyJaGG7Mt7vQ==", + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", + "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", @@ -6544,17 +6544,17 @@ "deprecated": "This version has been deprecated and is no longer supported or maintained" }, "node_modules/hapi-swagger": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/hapi-swagger/-/hapi-swagger-17.2.1.tgz", - "integrity": "sha512-IaF3OHfYjzDuyi5EQgS0j0xB7sbAAD4DaTwexdhPYqEBI/J7GWMXFbftGObCIOeMVDufjoSBZWeaarEkNn6/ww==", + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/hapi-swagger/-/hapi-swagger-17.3.0.tgz", + "integrity": "sha512-mAW3KtNbuOjT7lmdZ+aRYK0lrNymEfo7fMfyV75QpnmcJqe5lK7WxJKQwRNnFrhoszOz1dP96emWTrIHOzvFCw==", "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.1.0", + "@apidevtools/json-schema-ref-parser": "^11.7.0", "@hapi/boom": "^10.0.1", - "@hapi/hoek": "^11.0.2", + "@hapi/hoek": "^11.0.4", "handlebars": "^4.7.8", - "http-status": "^1.7.3", + "http-status": "^1.7.4", "swagger-parser": "^10.0.3", - "swagger-ui-dist": "^5.9.1" + "swagger-ui-dist": "^5.17.14" }, "engines": { "node": ">=16.0.0" @@ -6976,9 +6976,9 @@ } }, "node_modules/http-status": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.7.3.tgz", - "integrity": "sha512-GS8tL1qHT2nBCMJDYMHGkkkKQLNkIAHz37vgO68XKvzv+XyqB4oh/DfmMHdtRzfqSJPj1xKG2TaELZtlCz6BEQ==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.7.4.tgz", + "integrity": "sha512-c2qSwNtTlHVYAhMj9JpGdyo0No/+DiKXCJ9pHtZ2Yf3QmPnBIytKSRT7BuyIiQ7icXLynavGmxUqkOjSrAuMuA==", "engines": { "node": ">= 0.4.0" } @@ -9632,9 +9632,9 @@ } }, "node_modules/npm-check-updates": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.0.3.tgz", - "integrity": "sha512-3UWnsnijmx4u9GnICHVCChz6JnhVLmYWqazoedWjLSY6hZB/QhMCps07vBbDmjWnHMhpl6YseAtFlvGbUq9Yrw==", + "version": "17.0.6", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.0.6.tgz", + "integrity": "sha512-KCiaJH1cfnh/RyzKiDNjNfXgcKFyQs550Uf1OF/Yzb8xO56w+RLpP/OKRUx23/GyP/mLYwEpOO65qjmVdh6j0A==", "dev": true, "bin": { "ncu": "build/cli.js", @@ -13207,9 +13207,9 @@ } }, "node_modules/swagger-ui-dist": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.9.3.tgz", - "integrity": "sha512-/OgHfO96RWXF+p/EOjEnvKNEh94qAG/VHukgmVKh5e6foX9kas1WbjvQnDDj0sSTAMr9MHRBqAWytDcQi0VOrg==" + "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz", + "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==" }, "node_modules/swagger2openapi": { "version": "7.0.8", diff --git a/package.json b/package.json index 70746b000..5c74c7e72 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "glob": "10.4.3", "hapi-auth-basic": "5.0.0", "hapi-auth-bearer-token": "8.0.0", - "hapi-swagger": "17.2.1", + "hapi-swagger": "17.3.0", "ilp-packet": "2.2.0", "knex": "3.1.0", "lodash": "4.17.21", @@ -133,7 +133,7 @@ "jsdoc": "4.0.3", "jsonpath": "1.1.1", "nodemon": "3.1.4", - "npm-check-updates": "17.0.3", + "npm-check-updates": "17.0.6", "nyc": "17.0.0", "pre-commit": "1.2.2", "proxyquire": "2.1.3",