From 3bb98a5231d7e44b97ad141642dbbe59cad136ee Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Wed, 27 May 2020 08:50:56 -0500 Subject: [PATCH 01/34] Updated parties to support account information. (#50) * Updated parties to support account information. * Added yars-parser to audit ignore list. * Addressed comments. --- src/audit-resolve.json | 40 ++++++++++++++++++++++++--------- src/docker-compose.yml | 2 +- src/models/constants.js | 13 +++++++++++ src/models/model.js | 2 ++ src/models/party.js | 49 ++++++++++++++++++++++++++++++++++++++--- src/test-api/api.yaml | 26 ++++++++++++++++++++++ src/test/constants.js | 12 ++++++++++ src/test/model.js | 12 ++++++++++ 8 files changed, 141 insertions(+), 15 deletions(-) diff --git a/src/audit-resolve.json b/src/audit-resolve.json index 902945d6..370b7362 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -1,14 +1,32 @@ { - "1300|nyc>istanbul-reports>handlebars": { - "fix": 1 + "decisions": { + "1300|nyc>istanbul-reports>handlebars": { + "madeAt": 0, + "decision": "fix" + }, + "1316|nyc>istanbul-reports>handlebars": { + "madeAt": 0, + "decision": "fix" + }, + "1324|nyc>istanbul-reports>handlebars": { + "madeAt": 0, + "decision": "fix" + }, + "1325|nyc>istanbul-reports>handlebars": { + "madeAt": 0, + "decision": "fix" + }, + "1500|npm-audit-resolver>yargs-unparser>yargs>yargs-parser": { + "decision": "ignore", + "madeAt": 1590450688208, + "expiresAt": 1593042654156 + }, + "1500|npm-audit-resolver>audit-resolve-core>yargs-parser": { + "decision": "ignore", + "madeAt": 1590450692169, + "expiresAt": 1593042654156 + } }, - "1316|nyc>istanbul-reports>handlebars": { - "fix": 1 - }, - "1324|nyc>istanbul-reports>handlebars": { - "fix": 1 - }, - "1325|nyc>istanbul-reports>handlebars": { - "fix": 1 - } + "rules": {}, + "version": 1 } \ No newline at end of file diff --git a/src/docker-compose.yml b/src/docker-compose.yml index acbafa1f..c5f3b5c1 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -19,4 +19,4 @@ services: - "3500:3000" - "3501:4000" depends_on: - - redis \ No newline at end of file + - redis diff --git a/src/models/constants.js b/src/models/constants.js index 0d8929ad..45bb3a1a 100644 --- a/src/models/constants.js +++ b/src/models/constants.js @@ -22,6 +22,7 @@ ******/ 'use strict'; +const partyAccountsTable = 'account'; const partyTable = 'party'; const quoteTable = 'quote'; const transactionRequestTable = 'transactionRequest'; @@ -78,6 +79,16 @@ CREATE TABLE IF NOT EXISTS ${transferTable} ( ) `; +const createAccountTable = ` +CREATE TABLE IF NOT EXISTS ${partyAccountsTable} ( + address TEXT NOT NULL PRIMARY KEY, + currency TEXT NOT NULL, + description TEXT NOT NULL, + idValue TEXT NOT NULL, + FOREIGN KEY (idValue) REFERENCES party(idValue) ON DELETE CASCADE +) +`; + module.exports = { partyTable, quoteTable, @@ -89,4 +100,6 @@ module.exports = { transferTable, partyExtensionTable, createPartyExtensionTable, + partyAccountsTable, + createAccountTable, }; diff --git a/src/models/model.js b/src/models/model.js index ea655476..5c659e59 100644 --- a/src/models/model.js +++ b/src/models/model.js @@ -40,6 +40,7 @@ const { createQuoteTable, createTransactionRequestTable, createPartyExtensionTable, + createAccountTable, } = require('./constants'); /** @@ -89,6 +90,7 @@ module.exports = class Model { await this.db.run(createTransactionRequestTable); await this.db.run(createTransferTable); await this.db.run(createPartyExtensionTable); + await this.db.run(createAccountTable); this.party = new Party(this.db); this.quote = new Quote(this.db); diff --git a/src/models/party.js b/src/models/party.js index bbff6198..737f083b 100644 --- a/src/models/party.js +++ b/src/models/party.js @@ -28,7 +28,7 @@ * @description Defines the party model structure and operations within the simulator. */ -const { partyTable, partyExtensionTable } = require('./constants'); +const { partyTable, partyExtensionTable, partyAccountsTable } = require('./constants'); /** @@ -51,7 +51,12 @@ module.exports = class Party { */ async get(idType, idValue) { - const res = await this.db.all(`SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, pe.key, pe.value FROM ${partyTable} p LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue WHERE p.idType = ? AND p.idValue = ?`, [idType, idValue]); + const res = await this.db.all(` + SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, pe.key, pe.value, pa.address, pa.currency, pa.description + FROM ${partyTable} p + LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue + LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue + WHERE p.idType = ? AND p.idValue = ?`, [idType, idValue]); const resultMap = {}; res.forEach((row) => { let party; @@ -75,6 +80,16 @@ module.exports = class Party { } party.extensionList.push({ key: row.key, value: row.value }); } + if (row.address) { + if (!party.accounts) { + party.accounts = []; + } + party.accounts.push({ + address: row.address, + currency: row.currency, + description: row.description, + }); + } }); if (res.length && res.length > 0) { return Object.values(resultMap)[0]; @@ -89,7 +104,11 @@ module.exports = class Party { * @returns {Promise} Party object. */ async getAll() { - const res = await this.db.all(`SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, pe.key, pe.value FROM ${partyTable} p LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue`); + const res = await this.db.all(` + SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, pe.key, pe.value, pa.address, pa.currency, pa.description + FROM ${partyTable} p + LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue + LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue`); const resultMap = {}; res.forEach((row) => { let party; @@ -113,6 +132,16 @@ module.exports = class Party { } party.extensionList.push({ key: row.key, value: row.value }); } + if (row.address) { + if (!party.accounts) { + party.accounts = []; + } + party.accounts.push({ + address: row.address, + currency: row.currency, + description: row.description, + }); + } }); return Object.values(resultMap); } @@ -141,6 +170,13 @@ module.exports = class Party { [idValue, extension.key, extension.value]); }); } + if (party.accounts) { + const { accounts } = party; + await Promise.all(accounts.map(async (account) => this.db.get(` + INSERT INTO ${partyAccountsTable} (idValue, address, currency, description) + VALUES (?, ?, ?, ?)`, + [idValue, account.address, account.currency, account.description]))); + } } @@ -181,6 +217,13 @@ module.exports = class Party { [idValue, extension.key, extension.value]); }); } + if (newParty.accounts) { + const { accounts } = newParty; + await Promise.all(accounts.map(async (account) => this.db.run(` + INSERT OR IGNORE INTO ${partyAccountsTable} (idValue, address, currency, description) + VALUES (?, ?, ?, ?);`, + [idValue, account.address, account.currency, account.description]))); + } } /** diff --git a/src/test-api/api.yaml b/src/test-api/api.yaml index cb2c1053..07e3c860 100644 --- a/src/test-api/api.yaml +++ b/src/test-api/api.yaml @@ -173,6 +173,8 @@ components: maxLength: 128 extensionList: $ref: '#/components/schemas/ExtensionList' + accounts: + $ref: '#/components/schemas/AccountList' Extension: type: object required: @@ -193,6 +195,30 @@ components: $ref: '#/components/schemas/Extension' title: ExtensionList description: Data model for the complex type ExtensionList + Account: + type: object + required: + - address + - currency + - description + properties: + address: + type: string + description: The routable address of this account. + currency: + type: string + description: The currency of the account. + description: + type: string + description: The name of the account. + title: Account + description: Data model for the complex type Account + AccountList: + type: array + items: + $ref: '#/components/schemas/Account' + title: AccountList + description: Data model for the complex type accountList idType: type: string enum: diff --git a/src/test/constants.js b/src/test/constants.js index 92e86f86..c7f2a8fc 100644 --- a/src/test/constants.js +++ b/src/test/constants.js @@ -64,6 +64,18 @@ const partyCreate = { value: '12345343', }, ], + accounts: [ + { + currency: 'USD', + description: 'savings', + address: 'moja.blue.8f027046-b82a-4fa9-838b-514514543785', + }, + { + currency: 'USD', + description: 'checking', + address: 'moja.blue.8f027046-b82a-4fa9-838b-70210fcf8137', + }, + ], }; diff --git a/src/test/model.js b/src/test/model.js index aba1ac27..dcb55242 100644 --- a/src/test/model.js +++ b/src/test/model.js @@ -103,6 +103,18 @@ test('create and update a party', async (t) => { value: '12345343', }, ], + accounts: [ + { + currency: 'USD', + description: 'savings', + address: 'moja.blue.8f027046-b82a-4fa9-838b-100000000000', + }, + { + currency: 'USD', + description: 'savings', + address: 'moja.blue.8f027046-b82a-4fa9-838b-200000000000', + }, + ], }; await model.party.create(partyCreate); const orig = await model.party.get(idType, idValue); From db9e05bde4efe173dce29542c71a1b185605bfa2 Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Thu, 28 May 2020 23:09:54 -0500 Subject: [PATCH 02/34] Edited CI to build PISP docker image. (#51) --- .circleci/config.yml | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 79487703..111151fa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,8 +42,17 @@ defaults_build_docker_publish: &defaults_build_docker_publish command: | echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG" docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG + case "$CIRCLE_TAG" in + *-pisp*) + # Don't update `late5t` for an image that has a `-pisp` + echo 'skipping late5t tag' + exit 0 + ;; + *) + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG + ;; + esac defaults_deploy_config_kubernetes_cluster: &defaults_deploy_config_kubernetes_cluster name: Configure Kubernetes cluster @@ -118,7 +127,7 @@ defaults_license_scanner: &defaults_license_scanner # defaults_working_directory: &defaults_working_directory -# # The working directory for this project (place where package.json is) is /src, +# # The working directory for this project (place where package.json is) is /src, # # as opposed to the project root # working_directory: /home/circleci/project/git @@ -132,7 +141,7 @@ defaults_slack_announcement: &defaults_slack_announcement -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" src_working_directory: &src_working_directory - # The working directory for this project (place where package.json is) is /src, + # The working directory for this project (place where package.json is) is /src, # as opposed to the project root working_directory: /home/circleci/project/git/src @@ -145,7 +154,7 @@ src_working_directory: &src_working_directory executors: default-docker: working_directory: /home/circleci/project/git - docker: + docker: - image: node:12.16.0-alpine default-machine: @@ -155,7 +164,7 @@ executors: helm-kube: working_directory: /home/circleci/project - docker: + docker: - image: hypnoglow/kubernetes-helm ## @@ -273,7 +282,7 @@ jobs: <<: *src_working_directory - run: name: Check for new npm vulnerabilities - command: npm run audit:check --silent -- --json > ./audit/results/auditResults.json + command: npm run audit:check --silent -- --json > ./audit/results/auditResults.json <<: *src_working_directory - store_artifacts: path: ./src/audit/results @@ -418,7 +427,7 @@ jobs: aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive - + # TODO: Enable this when we want to increase the strictness of our security policies # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) # if [ $failCount -gt 0 ]; then @@ -451,7 +460,7 @@ jobs: <<: *defaults_build_docker_publish - run: <<: *defaults_slack_announcement - + # deploy: # executor: helm-kube # steps: @@ -477,7 +486,7 @@ jobs: # - run: # <<: *defaults_deploy_install_or_upgrade_helm_chart - + ## # Workflows # @@ -550,7 +559,7 @@ workflows: - audit-licenses filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)/ branches: ignore: - /.*/ @@ -560,7 +569,7 @@ workflows: - build filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)/ branches: ignore: - /.*/ @@ -570,7 +579,7 @@ workflows: - build filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)/ branches: ignore: - /.*/ @@ -581,7 +590,7 @@ workflows: - image-scan filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)/ branches: ignore: - - /.*/ \ No newline at end of file + - /.*/ From 30078bc18bec6660a370842b522b53b288336073 Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Wed, 10 Jun 2020 05:43:09 -0500 Subject: [PATCH 03/34] Updated CI. (#52) --- .circleci/config.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 111151fa..926015cb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,14 +18,14 @@ defaults_Dependencies: &defaults_Dependencies | npm install -g node-gyp defaults_awsCliDependencies: &defaults_awsCliDependencies | + apk upgrade --no-cache apk --no-cache add \ - python \ - py-pip \ + python3 \ + py3-pip \ groff \ less \ mailcap - pip install --upgrade awscli==1.14.5 s3cmd==2.0.1 python-magic - apk -v --purge del py-pip + pip3 install --upgrade pip awscli==1.14.5 s3cmd==2.0.1 python-magic defaults_build_docker_build: &defaults_build_docker_build name: Build Docker image @@ -559,7 +559,7 @@ workflows: - audit-licenses filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)?/ branches: ignore: - /.*/ @@ -569,7 +569,7 @@ workflows: - build filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)?/ branches: ignore: - /.*/ @@ -579,7 +579,7 @@ workflows: - build filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)?/ branches: ignore: - /.*/ @@ -590,7 +590,7 @@ workflows: - image-scan filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)/ + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)?/ branches: ignore: - /.*/ From 0e8d3996da1c5a151e27e872cd0c7476d47a81e2 Mon Sep 17 00:00:00 2001 From: sridharvoruganti <36686863+sridharvoruganti@users.noreply.github.com> Date: Thu, 9 Jul 2020 13:25:44 +0530 Subject: [PATCH 04/34] #321 Added getSignedChallenge to return U2F resp (#56) * #321 Added getSignedChallenge to return U2F resp * #321 fixed vulnerability issues --- src/audit-resolve.json | 288 +++++++++++++++++++++- src/simulator/api.yaml | 491 +++++++++++++++++++++++++++++++++++++- src/simulator/handlers.js | 18 ++ src/test/constants.js | 45 ++++ src/test/simulator.js | 11 +- 5 files changed, 847 insertions(+), 6 deletions(-) diff --git a/src/audit-resolve.json b/src/audit-resolve.json index 370b7362..e3e24c71 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -18,13 +18,293 @@ }, "1500|npm-audit-resolver>yargs-unparser>yargs>yargs-parser": { "decision": "ignore", - "madeAt": 1590450688208, - "expiresAt": 1593042654156 + "madeAt": 1594225894229, + "expiresAt": 1596817877348 }, "1500|npm-audit-resolver>audit-resolve-core>yargs-parser": { "decision": "ignore", - "madeAt": 1590450692169, - "expiresAt": 1593042654156 + "madeAt": 1594225913594, + "expiresAt": 1596817877348 + }, + "1523|ava>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|eslint>inquirer>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|eslint>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|eslint>table>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|npm-audit-resolver>yargs-unparser>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-optimise-call-expression>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904142, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/traverse>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|nyc>istanbul-lib-instrument>@babel/core>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 + }, + "1523|tap-xunit>xmlbuilder>lodash": { + "decision": "ignore", + "madeAt": 1594225904143, + "expiresAt": 1596817877348 } }, "rules": {}, diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index a232cd33..8270f131 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -215,6 +215,37 @@ paths: application/json: schema: $ref: '#/components/schemas/errorResponse' + + /signchallenge: + post: + summary: Requests a signed challenge + tags: + - Authorizations + requestBody: + description: An incoming authorization request + content: + application/json: + schema: + $ref: '#/components/schemas/authorizationsPostRequest' + responses: + 200: + description: Response containing details of the challenge + content: + application/json: + schema: + $ref: '#/components/schemas/U2FPinValue' + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' components: schemas: @@ -486,7 +517,465 @@ components: otpValue: type: string description: OTP value - + + U2FPinValue: + title: U2FPinValue + type: object + description: U2F challenge-response, where payer FSP verifies if the response provided by end-user device matches the previously registered key. + properties: + pinValue: + $ref: '#/components/schemas/U2FPIN' + description: U2F challenge-response. + counter: + $ref: '#/components/schemas/Integer' + description: Sequential counter used for cloning detection. Present only for U2F authentication. + required: + - pinValue + - counter + U2FPIN: + title: U2FPIN + type: string + pattern: ^\S{1,64}$ + minLength: 1 + maxLength: 64 + description: U2F challenge-response, where payer FSP verifies if the response provided by end-user device matches the previously registered key. + Counter: + title: Counter + $ref: '#/components/schemas/Integer' + description: Sequential counter used for cloning detection. Present only for U2F authentication. + RetriesLeft: + title: RetriesLeft + $ref: '#/components/schemas/Integer' + description: RetriesLeft is the number of retries left before the financial transaction is rejected. It must be expressed in the form of the data type Integer. retriesLeft=1 means that this is the last retry before the financial transaction is rejected. + Integer: + title: Integer + type: string + pattern: '^[1-9]\d*$' + description: >- + The API data type Integer is a JSON String consisting of digits only. + Negative numbers and leading zeroes are not allowed. The data type is + always limited to a specific number of digits. + AuthenticationType: + title: AuthenticationTypeEnum + type: string + enum: + - OTP + - QRCODE + - U2F + description: >- + Below are the allowed values for the enumeration AuthenticationType. - + OTP One-time password generated by the Payer FSP. - QRCODE QR code used + as One Time Password. + OtpValue: + title: OtpValue + type: string + pattern: '^\d{3,10}$' + description: >- + The API data type OtpValue is a JSON String of 3 to 10 characters, + consisting of digits only. Negative numbers are not allowed. One or more + leading zeros are allowed. + QRCODE: + title: QRCODE + type: string + pattern: ^\S{1,64}$ + minLength: 1 + maxLength: 64 + description: QR code used as One Time Password. + + AuthenticationValue: + title: AuthenticationValue + oneOf: + - $ref: '#/components/schemas/OtpValue' + - $ref: '#/components/schemas/QRCODE' + - $ref: '#/components/schemas/U2FPinValue' + description: Contains the authentication value. The format depends on the authentication type used in the AuthenticationInfo complex type. + Money: + title: Money + type: object + description: Data model for the complex type Money. + properties: + currency: + $ref: '#/components/schemas/Currency' + description: Currency of the amount. + amount: + $ref: '#/components/schemas/Amount' + description: Amount of Money. + required: + - currency + - amount + Amount: + title: Amount + type: string + pattern: '^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$' + description: >- + The API data type Amount is a JSON String in a canonical format that is + restricted by a regular expression for interoperability reasons. This + pattern does not allow any trailing zeroes at all, but allows an amount + without a minor currency unit. It also only allows four digits in the + minor currency unit; a negative value is not allowed. Using more than 18 + digits in the major currency unit is not allowed. + Currency: + title: CurrencyEnum + description: >- + The currency codes defined in ISO 4217 as three-letter alphabetic codes + are used as the standard naming representation for currencies. + type: string + minLength: 3 + maxLength: 3 + enum: + - AED + - AFN + - ALL + - AMD + - ANG + - AOA + - ARS + - AUD + - AWG + - AZN + - BAM + - BBD + - BDT + - BGN + - BHD + - BIF + - BMD + - BND + - BOB + - BRL + - BSD + - BTN + - BWP + - BYN + - BZD + - CAD + - CDF + - CHF + - CLP + - CNY + - COP + - CRC + - CUC + - CUP + - CVE + - CZK + - DJF + - DKK + - DOP + - DZD + - EGP + - ERN + - ETB + - EUR + - FJD + - FKP + - GBP + - GEL + - GGP + - GHS + - GIP + - GMD + - GNF + - GTQ + - GYD + - HKD + - HNL + - HRK + - HTG + - HUF + - IDR + - ILS + - IMP + - INR + - IQD + - IRR + - ISK + - JEP + - JMD + - JOD + - JPY + - KES + - KGS + - KHR + - KMF + - KPW + - KRW + - KWD + - KYD + - KZT + - LAK + - LBP + - LKR + - LRD + - LSL + - LYD + - MAD + - MDL + - MGA + - MKD + - MMK + - MNT + - MOP + - MRO + - MUR + - MVR + - MWK + - MXN + - MYR + - MZN + - NAD + - NGN + - NIO + - NOK + - NPR + - NZD + - OMR + - PAB + - PEN + - PGK + - PHP + - PKR + - PLN + - PYG + - QAR + - RON + - RSD + - RUB + - RWF + - SAR + - SBD + - SCR + - SDG + - SEK + - SGD + - SHP + - SLL + - SOS + - SPL + - SRD + - STD + - SVC + - SYP + - SZL + - THB + - TJS + - TMT + - TND + - TOP + - TRY + - TTD + - TVD + - TWD + - TZS + - UAH + - UGX + - USD + - UYU + - UZS + - VEF + - VND + - VUV + - WST + - XAF + - XCD + - XDR + - XOF + - XPF + - YER + - ZAR + - ZMW + - ZWD + CorrelationId: + title: CorrelationId + type: string + pattern: >- + ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ + description: >- + Identifier that correlates all messages of the same sequence. The API + data type UUID (Universally Unique Identifier) is a JSON String in + canonical format, conforming to RFC 4122, that is restricted by a + regular expression for interoperability reasons. An UUID is always 36 + characters long, 32 hexadecimal symbols and 4 dashes (‘-‘). + DateTime: + title: DateTime + type: string + pattern: >- + ^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$ + description: >- + The API data type DateTime is a JSON String in a lexical format that is + restricted by a regular expression for interoperability reasons. The + format is according to ISO 8601, expressed in a combined date, time and + time zone format. A more readable version of the format is + yyyy-MM-ddTHH:mm:ss.SSS[-HH:MM]. Examples - + "2016-05-24T08:38:08.699-04:00", "2016-05-24T08:38:08.699Z" (where Z + indicates Zulu time zone, same as UTC). + GeoCode: + title: GeoCode + type: object + description: >- + Data model for the complex type GeoCode. Indicates the geographic + location from where the transaction was initiated. + properties: + latitude: + $ref: '#/components/schemas/Latitude' + description: Latitude of the Party. + longitude: + $ref: '#/components/schemas/Longitude' + description: Longitude of the Party. + required: + - latitude + - longitude + Latitude: + title: Latitude + type: string + pattern: >- + ^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ + description: >- + The API data type Latitude is a JSON String in a lexical format that is + restricted by a regular expression for interoperability reasons. + Longitude: + title: Longitude + type: string + pattern: >- + ^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$ + description: >- + The API data type Longitude is a JSON String in a lexical format that is + restricted by a regular expression for interoperability reasons. + IlpCondition: + title: IlpCondition + type: string + pattern: '^[A-Za-z0-9-_]{43}$' + maxLength: 48 + description: Condition that must be attached to the transfer by the Payer. + IlpFulfilment: + title: IlpFulfilment + type: string + pattern: '^[A-Za-z0-9-_]{43}$' + maxLength: 48 + description: Fulfilment that must be attached to the transfer by the Payee. + IlpPacket: + title: IlpPacket + type: string + pattern: '^[A-Za-z0-9-_]+[=]{0,2}$' + minLength: 1 + maxLength: 32768 + description: Information for recipient (transport layer information). + ExtensionKey: + title: ExtensionKey + type: string + minLength: 1 + maxLength: 32 + description: Extension key. + ExtensionValue: + title: ExtensionValue + type: string + minLength: 1 + maxLength: 128 + description: Extension value. + Extension: + title: Extension + type: object + description: Data model for the complex type Extension + properties: + key: + $ref: '#/components/schemas/ExtensionKey' + description: Extension key. + value: + $ref: '#/components/schemas/ExtensionValue' + description: Extension value. + required: + - key + - value + ExtensionList: + title: ExtensionList + type: object + description: Data model for the complex type ExtensionList + properties: + extension: + type: array + items: + $ref: '#/components/schemas/Extension' + minItems: 1 + maxItems: 16 + description: Number of Extension elements + required: + - extension + + QuotesIDPutResponse: + title: QuotesIDPutResponse + type: object + description: 'PUT /quotes/{ID} object' + properties: + transferAmount: + $ref: '#/components/schemas/Money' + description: >- + The amount of Money that the Payer FSP should transfer to the Payee + FSP. + payeeReceiveAmount: + $ref: '#/components/schemas/Money' + description: >- + The amount of Money that the Payee should receive in the end-to-end + transaction. Optional as the Payee FSP might not want to disclose + any optional Payee fees. + payeeFspFee: + $ref: '#/components/schemas/Money' + description: Payee FSP’s part of the transaction fee. + payeeFspCommission: + $ref: '#/components/schemas/Money' + description: Transaction commission from the Payee FSP. + expiration: + $ref: '#/components/schemas/DateTime' + description: >- + Date and time until when the quotation is valid and can be honored + when used in the subsequent transaction. + geoCode: + $ref: '#/components/schemas/GeoCode' + description: Longitude and Latitude of the Payee. Can be used to detect fraud. + ilpPacket: + $ref: '#/components/schemas/IlpPacket' + description: The ILP Packet that must be attached to the transfer by the Payer. + condition: + $ref: '#/components/schemas/IlpCondition' + description: The condition that must be attached to the transfer by the Payer. + extensionList: + $ref: '#/components/schemas/ExtensionList' + description: 'Optional extension, specific to deployment.' + required: + - transferAmount + - expiration + - ilpPacket + - condition + authorizationsPostRequest: + title: authorizationsPostRequest + type: object + description: POST /authorizations Request object + properties: + authenticationType: + $ref: '#/components/schemas/AuthenticationType' + description: This value is a valid authentication type from the enumeration AuthenticationType(OTP or QR Code or U2F). + retriesLeft: + $ref: '#/components/schemas/RetriesLeft' + description: RetriesLeft is the number of retries left before the financial transaction is rejected. It must be expressed in the form of the data type Integer. retriesLeft=1 means that this is the last retry before the financial transaction is rejected. + amount: + $ref: '#/components/schemas/Money' + description: This is the transaction amount that will be withdrawn from the Payer’s account. + transactionId: + $ref: '#/components/schemas/CorrelationId' + description: Common ID (decided by the Payer FSP) between the FSPs for the future transaction object. The actual transaction will be created as part of a successful transfer process. + transactionRequestId: + $ref: '#/components/schemas/CorrelationId' + description: The transactionRequestID, received from the POST /transactionRequests service earlier in the process. + quote: + $ref: '#/components/schemas/QuotesIDPutResponse' + description: Quotes object + required: + - authenticationType + - retriesLeft + - amount + - transactionId + - transactionRequestId + - quote + transferStatus: type: string enum: diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index 4e57f773..69cfb5ff 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -23,6 +23,7 @@ 'use strict'; const util = require('util'); +const crypto = require('crypto'); require('dotenv').config(); const { getStackOrInspect } = require('@internal/log'); const { ApiErrorCodes } = require('../models/errors.js'); @@ -77,6 +78,20 @@ const getOTPById = async (ctx) => { } }; +const getSignedChallenge = async (ctx) => { + try { + const res = { + pinValue: crypto.randomBytes(256).toString('base64').slice(0, 64), + counter: '1', + }; + ctx.state.logger.log(`getSignedChallenge is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; + } catch (err) { + ctx.response.body = ApiErrorCodes.SERVER_ERROR; + ctx.response.status = 500; + } +}; const postTransfers = async (ctx) => { try { @@ -144,6 +159,9 @@ const map = { '/transfers': { post: postTransfers, }, + '/signchallenge': { + post: getSignedChallenge, + }, '/otp/{requestToPayId}': { get: getOTPById, }, diff --git a/src/test/constants.js b/src/test/constants.js index c7f2a8fc..1df368b4 100644 --- a/src/test/constants.js +++ b/src/test/constants.js @@ -120,6 +120,50 @@ const transactionrequest = { initiatorType: 'CONSUMER', }; +const authorizationRequest = { + authenticationType: 'U2F', + retriesLeft: '1', + amount: { + currency: 'USD', + amount: '100', + }, + transactionId: '2f169631-ef99-4cb1-96dc-91e8fc08f539', + transactionRequestId: '02e28448-3c05-4059-b5f7-d518d0a2d8ea', + quote: { + transferAmount: { + currency: 'USD', + amount: '100', + }, + payeeReceiveAmount: { + currency: 'USD', + amount: '99', + }, + payeeFspFee: { + currency: 'USD', + amount: '1', + }, + payeeFspCommission: { + currency: 'USD', + amount: '0', + }, + expiration: '2020-05-17T15:28:54.250Z', + geoCode: { + latitude: '+45.4215', + longitude: '+75.6972', + }, + ilpPacket: 'AYIBgQAAAAAAAASwNGxldmVsb25lLmRmc3AxLm1lci45T2RTOF81MDdqUUZERmZlakgy...', + condition: 'f5sqb7tBTWPd5Y8BDFdMm9BJR_MNI4isf8p8n4D5pHA', + extensionList: { + extension: [ + { + key: 'errorDescription1', + value: 'This is a more detailed error description', + }, + ], + }, + }, +}; + const transfer = { transferId, quote: { @@ -209,5 +253,6 @@ module.exports = { idType, idValue, transferId, + authorizationRequest, transactionRequestId, }; diff --git a/src/test/simulator.js b/src/test/simulator.js index b46e531f..4851fa28 100644 --- a/src/test/simulator.js +++ b/src/test/simulator.js @@ -28,7 +28,7 @@ const Model = require('../models/model'); const { map } = require('../simulator/handlers'); const { transfer, transferWithoutQuote, quote, transactionrequest, party, idType, idValue, - transactionRequestId, + transactionRequestId, authorizationRequest, } = require('./constants'); const { ApiErrorCodes } = require('../models/errors'); @@ -87,6 +87,15 @@ test('create a transactionrequest', async (t) => { t.is(t.context.response.status, 200); }); +test('get signed challenge', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { body: authorizationRequest }; + await map['/signchallenge'].post(t.context); + t.truthy(t.context.response.body); + t.assert({}.hasOwnProperty.call(t.context.response.body, 'pinValue')); + t.is(t.context.response.status, 200); +}); + test('create a transfer without a quote', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { body: transferWithoutQuote }; From 4a5cbbf790b264a658dddd051a7e6dbc4d6c16fc Mon Sep 17 00:00:00 2001 From: eoln <2881004+eoln@users.noreply.github.com> Date: Wed, 15 Jul 2020 15:59:27 +0200 Subject: [PATCH 05/34] Pisp/305 authorizations (#64) * chore(swagger): add post /authorizations path * fix: rewrite content-type header to be compatible with sdk-standard-components --- src/index.js | 26 ++++++++++++++++++++++++++ src/simulator/api.yaml | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/index.js b/src/index.js index c3c25b5d..6d490b77 100644 --- a/src/index.js +++ b/src/index.js @@ -58,6 +58,30 @@ const simulator = new Koa(); const report = new Koa(); const testApi = new Koa(); +/* + when using simulator with sdk-standard-components ThirdpartyRequests + the need to rewrite content-type header appears because koaBody has problems + with interoperability headers and doesn't parse properly the request body +*/ + + +// map where keys are the content-type values to be rewritten, extend it if needed +const rewriteContentTypes = { + 'application/vnd.interoperability.authorizations+json;version=1.0': 'application/json', +}; + +// rewrite content-type header middleware +async function rewriteContentTypeHeader(ctx, next) { + const contentType = ctx.header['content-type']; + + // rewrite only if contentType found in rewriteContentTypes + // elsewhere keep original value + ctx.header['content-type'] = rewriteContentTypes[contentType] || contentType; + + await next(); +} + + (async function start() { // Set up the config from the environment await setConfig(process.env); @@ -141,6 +165,7 @@ const testApi = new Koa(); ctx.state.logger.log('Request processed'); }); + simulator.use(rewriteContentTypeHeader); simulator.use(koaBody()); report.use(koaBody()); @@ -153,6 +178,7 @@ const testApi = new Koa(); simulator.use(async (ctx, next) => { ctx.state.logger.log('Validating request'); try { + ctx.state.logger.push({ ctx_request: ctx.request }).log('validating request'); ctx.state.path = simValidator.validateRequest(ctx, ctx.state.logger); ctx.state.logger.log('Request passed validation'); ctx.state.model = model; diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 8270f131..445f0226 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -226,22 +226,51 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/authorizationsPostRequest' + $ref: '#/components/schemas/AuthorizationsPostRequest' responses: 200: description: Response containing details of the challenge + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request content: application/json: schema: - $ref: '#/components/schemas/U2FPinValue' + $ref: '#/components/schemas/errorResponse' + /authorizations: + post: + tags: + - Authorizations + description: The HTTP request `POST /authorizations` is used to request the Payer to enter the applicable credentials in the PISP system. + summary: /authorizations + operationId: AuthorizationsPost + requestBody: + description: Perform authorization + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuthorizationsPostRequest' + responses: + 200: + description: 'post accepted' + content: + application/json: + schema: + type: object 400: - description: Malformed or missing required headers or parameters + description: 'invalid request' content: application/json: schema: $ref: '#/components/schemas/errorResponse' 500: - description: An error occured processing the request + description: 'internal server error' content: application/json: schema: @@ -945,8 +974,8 @@ components: - expiration - ilpPacket - condition - authorizationsPostRequest: - title: authorizationsPostRequest + AuthorizationsPostRequest: + title: AuthorizationsPostRequest type: object description: POST /authorizations Request object properties: From dd65f172980f3b071f564e7f20033c450c6ba513 Mon Sep 17 00:00:00 2001 From: eoln <2881004+eoln@users.noreply.github.com> Date: Wed, 15 Jul 2020 15:59:27 +0200 Subject: [PATCH 06/34] Pisp/305 POST /authorizations (#64) * chore(swagger): add post /authorizations path * fix: rewrite content-type header to be compatible with sdk-standard-components --- src/index.js | 26 ++++++++++++++++++++++++++ src/simulator/api.yaml | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/index.js b/src/index.js index c3c25b5d..6d490b77 100644 --- a/src/index.js +++ b/src/index.js @@ -58,6 +58,30 @@ const simulator = new Koa(); const report = new Koa(); const testApi = new Koa(); +/* + when using simulator with sdk-standard-components ThirdpartyRequests + the need to rewrite content-type header appears because koaBody has problems + with interoperability headers and doesn't parse properly the request body +*/ + + +// map where keys are the content-type values to be rewritten, extend it if needed +const rewriteContentTypes = { + 'application/vnd.interoperability.authorizations+json;version=1.0': 'application/json', +}; + +// rewrite content-type header middleware +async function rewriteContentTypeHeader(ctx, next) { + const contentType = ctx.header['content-type']; + + // rewrite only if contentType found in rewriteContentTypes + // elsewhere keep original value + ctx.header['content-type'] = rewriteContentTypes[contentType] || contentType; + + await next(); +} + + (async function start() { // Set up the config from the environment await setConfig(process.env); @@ -141,6 +165,7 @@ const testApi = new Koa(); ctx.state.logger.log('Request processed'); }); + simulator.use(rewriteContentTypeHeader); simulator.use(koaBody()); report.use(koaBody()); @@ -153,6 +178,7 @@ const testApi = new Koa(); simulator.use(async (ctx, next) => { ctx.state.logger.log('Validating request'); try { + ctx.state.logger.push({ ctx_request: ctx.request }).log('validating request'); ctx.state.path = simValidator.validateRequest(ctx, ctx.state.logger); ctx.state.logger.log('Request passed validation'); ctx.state.model = model; diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 8270f131..445f0226 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -226,22 +226,51 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/authorizationsPostRequest' + $ref: '#/components/schemas/AuthorizationsPostRequest' responses: 200: description: Response containing details of the challenge + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request content: application/json: schema: - $ref: '#/components/schemas/U2FPinValue' + $ref: '#/components/schemas/errorResponse' + /authorizations: + post: + tags: + - Authorizations + description: The HTTP request `POST /authorizations` is used to request the Payer to enter the applicable credentials in the PISP system. + summary: /authorizations + operationId: AuthorizationsPost + requestBody: + description: Perform authorization + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuthorizationsPostRequest' + responses: + 200: + description: 'post accepted' + content: + application/json: + schema: + type: object 400: - description: Malformed or missing required headers or parameters + description: 'invalid request' content: application/json: schema: $ref: '#/components/schemas/errorResponse' 500: - description: An error occured processing the request + description: 'internal server error' content: application/json: schema: @@ -945,8 +974,8 @@ components: - expiration - ilpPacket - condition - authorizationsPostRequest: - title: authorizationsPostRequest + AuthorizationsPostRequest: + title: AuthorizationsPostRequest type: object description: POST /authorizations Request object properties: From c005a38967c5453090c9988fe6b7eda368be0717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marzec?= Date: Thu, 16 Jul 2020 09:02:04 +0200 Subject: [PATCH 07/34] ci: setup checkout after installing default dependenices --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 926015cb..ebbe97cc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -176,10 +176,10 @@ jobs: setup: executor: default-docker steps: - - checkout - run: name: Install general dependencies command: *defaults_Dependencies + - checkout # - run: # name: Build dependencies # command: apk add --no-cache -t build-dependencies make gcc g++ python libtool autoconf automake @@ -201,10 +201,10 @@ jobs: test-unit: executor: default-docker steps: - - checkout - run: name: Install general dependencies command: *defaults_Dependencies + - checkout - restore_cache: key: dependency-cache-{{ checksum "./src/package.json" }} - run: @@ -232,10 +232,10 @@ jobs: test-coverage: executor: default-docker steps: - - checkout - run: name: Install general dependencies command: *defaults_Dependencies + - checkout - run: name: Install AWS CLI dependencies command: *defaults_awsCliDependencies @@ -270,10 +270,10 @@ jobs: vulnerability-check: executor: default-docker steps: - - checkout - run: name: Install general dependencies command: *defaults_Dependencies + - checkout - restore_cache: key: dependency-cache-{{ checksum "./src/package.json" }} - run: @@ -291,10 +291,10 @@ jobs: audit-licenses: executor: default-docker steps: - - checkout - run: name: Install general dependencies command: *defaults_Dependencies + - checkout - run: <<: *defaults_license_scanner - restore_cache: From 1e297a410e7f03debd2c72adb85937e4f7662193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marzec?= <2881004+eoln@users.noreply.github.com> Date: Fri, 9 Oct 2020 16:04:47 +0200 Subject: [PATCH 08/34] feat: 1671 verify authorization (#82) * feat(api): add /verify-authorization endpoint * chore(audit): ignore for one month --- src/audit-resolve.json | 237 +++++++++++++++++++++-------------------- src/simulator/api.yaml | 81 +++++++++++++- 2 files changed, 200 insertions(+), 118 deletions(-) diff --git a/src/audit-resolve.json b/src/audit-resolve.json index e3e24c71..82d269f5 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -18,293 +18,298 @@ }, "1500|npm-audit-resolver>yargs-unparser>yargs>yargs-parser": { "decision": "ignore", - "madeAt": 1594225894229, - "expiresAt": 1596817877348 + "madeAt": 1602252044897, + "expiresAt": 1604844018565 }, "1500|npm-audit-resolver>audit-resolve-core>yargs-parser": { "decision": "ignore", - "madeAt": 1594225913594, - "expiresAt": 1596817877348 + "madeAt": 1602252039657, + "expiresAt": 1604844018565 }, "1523|ava>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|eslint>inquirer>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|eslint>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|eslint>table>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|npm-audit-resolver>yargs-unparser>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-optimise-call-expression>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904142, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/template>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-split-export-declaration>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/types>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/traverse>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|nyc>istanbul-lib-instrument>@babel/core>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 }, "1523|tap-xunit>xmlbuilder>lodash": { "decision": "ignore", - "madeAt": 1594225904143, - "expiresAt": 1596817877348 + "madeAt": 1602252048123, + "expiresAt": 1604844018565 + }, + "1556|node-fetch": { + "decision": "ignore", + "madeAt": 1602252035571, + "expiresAt": 1604844018565 } }, "rules": {}, diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 445f0226..716ca5a0 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -275,7 +275,39 @@ paths: application/json: schema: $ref: '#/components/schemas/errorResponse' - + /verify-authorization: + post: + tags: + - Authorizations + description: The HTTP request `POST /verify-authorization` is used to verify signed authorization received from PISP. + summary: /verify-authorization + operationId: VerifyAuthorizationsPost + requestBody: + description: Perform verification of signed authorization + required: true + content: + application/json: + schema: + type: object + responses: + 200: + description: 'post accepted' + content: + application/json: + schema: + type: object + 400: + description: 'invalid request' + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: 'internal server error' + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' components: schemas: @@ -1130,7 +1162,52 @@ components: type: string description: Error message text + AuthenticationInfo: + title: AuthenticationInfo + type: object + description: Data model for the complex type AuthenticationInfo + properties: + authentication: + $ref: '#/components/schemas/AuthenticationType' + description: Type of authentication. + authenticationValue: + $ref: '#/components/schemas/AuthenticationValue' + description: Authentication value. + required: + - authentication + - authenticationValue + VerifyAuthorizationsPostRequest: + title: AuthorizationsIDPutResponse + type: object + description: 'POST /verify-authorizations' + properties: + authenticationInfo: + $ref: '#/components/schemas/AuthenticationInfo' + description: 'OTP or QR Code if entered, otherwise empty.' + responseType: + $ref: '#/components/schemas/AuthorizationResponse' + description: >- + Enum containing response information; if the customer entered the + authentication value, rejected the transaction, or requested a + resend of the authentication value. + transactionRequestId: + $ref: '#/components/schemas/transactionRequestId' + required: + - responseType + - authenticationInfo + - transactionRequestId - + AuthorizationResponse: + title: AuthorizationResponse + type: string + enum: + - ENTERED + - REJECTED + - RESEND + description: >- + Below are the allowed values for the enumeration - ENTERED Consumer + entered the authentication value. - REJECTED Consumer rejected the + transaction. - RESEND Consumer requested to resend the authentication + value. From 499841df2f5f77c36e6484148b3b96b9510c2a11 Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Tue, 29 Dec 2020 05:40:40 -0500 Subject: [PATCH 09/34] chore: sync pisp/master to v11.3.0 (#87) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #1325: Bulk transfers and bulk quotes support (#49) * Add support for bulk transfers * Add bulkTransfers call from backend to outbound API * Add bulk quotes support * WIP: Add bulk transfer model and handler * Fix audit issues * Make sim, report, and test ports configuraable * Restore default ports in docker-compose * Port config update * Updates for bulk quotes and bulk transfers * Add POST /bulkQuotes, remove PUT /bulkTransfers/{bulkTransferId}. Fix API spec bugs * Update unit test for config.js * Add tests for bulkQuotes model * Fix audit issues * Add tests for bulk quotes * Update unit tests for simulator handler * Format code * Update contributors list * Fix bug with POST bulkQuotes and tests * Update contributors list * Update api spec * Add getBulkQuoteById and getBulkTransferById * Add unit tests for bulk quotes and bulk transfers handlers * Resolve audit issues * Cleanup * Update package.json * Update src/package.json Co-authored-by: Sam <10507686+elnyry-sam-k@users.noreply.github.com> * Fix audit issues Co-authored-by: Sam <10507686+elnyry-sam-k@users.noreply.github.com> * Hotfix: Fix python dependencies in CI (#53) * Upgrade python for CI build * Update ci config * Bump version * Update pipeline (#54) * Add orbs * Update dependencies to Python@3 * Simplify defaults * Update to Python@3 * Remove comments * Remove unecessary executor * Update config * Use pip3 * Remove unused step * Update * Test * Test * Remove anchor for working directory * Update node * Test * Fix YAML syntax * Use anchor * Fix directory issue * Fix path * Add path to restore_cache * Test * Test * Update key * Update dependencies * Fix path * Add submodule dependencies to cache * Version dependency cache * Fix path * Test * Change directory to src * Allow build-local to run in parallel from the start * Add Init Container To Onboard MSISDN's (#55) * Add init container to onboard with central-ledger * Remove environment var processing script * Switch RUN to CMD * Add OCI labels * Add contributor * Update init/central-ledger/Dockerfile Co-Authored-By: Matt Kingston * Clear whitespace and unused comments * Add build and publish to CI for init-central-ledger * Fix indentation * created insert msisnd script * complete docker container and MSISDN onboarding script * change MSISDN_LIST name * change script to handle MSISDN data * ignore dependency vulneravility * update dockerfile * rename * change pathfinder url name * modify scripts * fix script and docker container * add CI pipeline and remove unused files * fix docker command * fix indentation * fix tag implementation * yaml is fun * resolve vulnerabilities and fix docker save * fix docker build * fix docker image naming and add Matt suggestion * log current images * idk why but it works now * Clean up naming and pipeline * Bump version Co-authored-by: Kamuela Franco Co-authored-by: Matt Kingston * Fix publish for onboard-msisdn-oracle in pipeline (#58) * Fix publish for onboard-msisdn-oracle in pipeline * Bump version * Add init container to onboard with central-ledger (#48) * Add init container to onboard with central-ledger * Remove environment var processing script * Switch RUN to CMD * Add OCI labels * Add contributor * Update init/central-ledger/Dockerfile Co-Authored-By: Matt Kingston * Clear whitespace and unused comments * Add build and publish to CI for init-central-ledger * Fix indentation * Update .circleci/config.yml Co-authored-by: Matt Kingston * Add ESLint and node-fetch * Update config to master branch * Add onboarding steps * Update finance-portal-lib dependency * Add logging * Update Dockerfile * Add items to .gitignore * Align output * Graceful exit on failure * Add log output * Add detailed logging on error * Update finance-portal-lib dependency * Add more detailed logging * Allow re-registration of same DFSP name and currency * Fix bug * Fix output by calling script directly * Fix logging and request edge cases * Add onboard-central-ledger to pipeline * Bump version * Add comments * Fix build argument references * Require setup for local builds * Update init/onboard-central-ledger/onboard-dfsp.js Co-authored-by: Matt Kingston * Log script commands and exit on error * Exit when required variable is not present Co-authored-by: Matt Kingston * Fix erroneous file name in pipeline (#59) * Fix file name * Bump version * Remove dependency on org secret for build pipeline (#61) * Remove dependency on org secret for build pipeline * Update config.yml * Fix bugs with API spec and model for bulk transfers (#62) * Fix erroneous use of environment variables for onboarding (#63) * Fix erroneous use of PARTY_ID and PARTY_ID_TYPE * Bump version * Fix build artifacts (#65) * Fix build artifacts * Bump version * Fix security issues * Fix build order dependency (#66) * Update finance-portal-lib in init container (#67) * Modified to reflect changes in dependency (#68) * Modified to reflect changes in dependency * Modified package version more * version stuff * Version bump * Version bump * Add hub onboarding image (#69) * Code written * Fixes, changes * Added onboard hub accounts to CI * Updated CI * Update init/onboard-hub-accounts/Dockerfile Co-authored-by: Kamuela Franco Co-authored-by: Kamuela Franco * Bump versions (#70) * Fixed onboard-hub-accounts Dockerfile error, bumped versions (#71) * Add image scans and vulnerability checks for inits (#74) * The chart in this repo is now redundant. Removing in favour of https://github.com/mojaloop/helm/tree/master/mojaloop-simulator. (#73) * Update README with init container docs (#76) * Update README with init container docs * Add values-sims.example.yaml * Remove link * [WIP] Feature/#1572 payee notification (#75) * upstream merge * added PUT /transfers/transferId handling for notifications to payee * added unit tests * ordered package.json to trigger ci/cd pipeline * removed homeTransactionId from transfer.update Co-authored-by: Valentin Co-authored-by: James Bush <37296643+bushjames@users.noreply.github.com> * Environment variable configuration of parties (#77) * Initial work- parties addable, but no tests, no functionality * Added test for preconfigured parties * Added config unit test * Update src/config.js * Update src/config.js * Updated config correctly. Duh. * Bumped version * Improved Model.init doc. Fixed bug with server start. Bumped version. (#78) * Bump node-fetch from 2.6.0 to 2.6.1 in /src (#79) Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/bitinn/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump node-fetch from 2.6.0 to 2.6.1 in /init/onboard-hub-accounts (#81) Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/bitinn/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump node-fetch from 2.6.0 to 2.6.1 in /init/onboard-central-ledger (#80) Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/bitinn/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(package): bump package to `11.2.2` (#83) * chore: update license file (#84) * Add "subIdValue" parameter for parties in simulator (#85) * added endpoint for subIdValue * added unit/coverage tests * fix linting * added simulator endpoints for subIdValue * fix audit issue * chore: fix merge issues Co-authored-by: Steven Oderayi Co-authored-by: Sam <10507686+elnyry-sam-k@users.noreply.github.com> Co-authored-by: Kamuela Franco Co-authored-by: Aarón Reynoza Co-authored-by: Matt Kingston Co-authored-by: Valentin Genev Co-authored-by: Valentin Co-authored-by: James Bush <37296643+bushjames@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lewis Daly Co-authored-by: shashi165 <33355509+shashi165@users.noreply.github.com> --- .circleci/config.yml | 2 + .dockerignore | 3 + .gitignore | 7 +- LICENSE.md | 8 +- README.md | 8 + docs/values-sims.example.yaml | 139 ++ helm/.gitignore | 3 - helm/.helmignore | 25 - helm/Chart.yaml | 5 - helm/templates/_helpers.tpl | 32 - helm/templates/config-jws-public-keys.yaml | 26 - helm/templates/config-rules.yaml | 15 - helm/templates/deployment.yaml | 259 --- helm/templates/horizontalpodautoscaler.yaml | 21 - helm/templates/ingress.yaml | 40 - helm/templates/secret.yaml | 22 - helm/templates/service.yaml | 77 - helm/values.yaml | 429 ---- init/onboard-central-ledger/.eslintrc.json | 6 + init/onboard-central-ledger/.gitignore | 1 + init/onboard-central-ledger/Dockerfile | 28 + init/onboard-central-ledger/onboard-dfsp.js | 464 +++++ init/onboard-central-ledger/package-lock.json | 1751 +++++++++++++++++ init/onboard-central-ledger/package.json | 24 + init/onboard-hub-accounts/Dockerfile | 28 + .../onboard-hub-accounts.js | 64 + init/onboard-hub-accounts/package-lock.json | 1751 +++++++++++++++++ init/onboard-hub-accounts/package.json | 24 + init/onboard-msisdn-oracle/Dockerfile | 22 + init/onboard-msisdn-oracle/insert_msisdns.sh | 18 + src/audit-resolve.json | 318 +-- src/config.js | 10 + src/index.js | 13 +- src/models/bulkQuote.js | 123 ++ src/models/bulkTransfer.js | 103 + src/models/constants.js | 63 +- src/models/model.js | 51 +- src/models/party.js | 173 +- src/models/transfer.js | 11 +- src/package-lock.json | 704 ++----- src/package.json | 8 +- src/sim-backend.env | 5 + src/simulator/api.yaml | 521 +++++ src/simulator/handlers.js | 106 +- src/test-api/api.yaml | 107 +- src/test-api/client.js | 40 +- src/test-api/handlers.js | 39 +- src/test/admin.js | 2 +- src/test/constants.js | 224 ++- src/test/model.js | 223 ++- src/test/reports.js | 2 +- src/test/simulator.js | 114 +- src/test/test-api.js | 148 +- src/test/unit/TestUtils.js | 13 + src/test/unit/config.test.js | 15 +- 55 files changed, 6476 insertions(+), 1962 deletions(-) create mode 100644 docs/values-sims.example.yaml delete mode 100644 helm/.gitignore delete mode 100644 helm/.helmignore delete mode 100644 helm/Chart.yaml delete mode 100644 helm/templates/_helpers.tpl delete mode 100644 helm/templates/config-jws-public-keys.yaml delete mode 100644 helm/templates/config-rules.yaml delete mode 100644 helm/templates/deployment.yaml delete mode 100644 helm/templates/horizontalpodautoscaler.yaml delete mode 100644 helm/templates/ingress.yaml delete mode 100644 helm/templates/secret.yaml delete mode 100644 helm/templates/service.yaml delete mode 100644 helm/values.yaml create mode 100644 init/onboard-central-ledger/.eslintrc.json create mode 100644 init/onboard-central-ledger/.gitignore create mode 100644 init/onboard-central-ledger/Dockerfile create mode 100644 init/onboard-central-ledger/onboard-dfsp.js create mode 100644 init/onboard-central-ledger/package-lock.json create mode 100644 init/onboard-central-ledger/package.json create mode 100644 init/onboard-hub-accounts/Dockerfile create mode 100644 init/onboard-hub-accounts/onboard-hub-accounts.js create mode 100644 init/onboard-hub-accounts/package-lock.json create mode 100644 init/onboard-hub-accounts/package.json create mode 100644 init/onboard-msisdn-oracle/Dockerfile create mode 100755 init/onboard-msisdn-oracle/insert_msisdns.sh create mode 100644 src/models/bulkQuote.js create mode 100644 src/models/bulkTransfer.js diff --git a/.circleci/config.yml b/.circleci/config.yml index ebbe97cc..7e86ee10 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,6 +3,8 @@ version: 2.1 orbs: anchore: anchore/anchore-engine@1.6.0 +# TODO: Further evaluate what changes need to be pulled from master. +# File has not been updated to v11.3.0 ## # defaults # diff --git a/.dockerignore b/.dockerignore index 04a8318e..c6e0e219 100644 --- a/.dockerignore +++ b/.dockerignore @@ -45,6 +45,9 @@ typings/ # Optional eslint cache .eslintcache +# ESlint config +.eslintrc.json + # Optional REPL history .node_repl_history diff --git a/.gitignore b/.gitignore index e47ab085..951bbeda 100644 --- a/.gitignore +++ b/.gitignore @@ -65,4 +65,9 @@ simulator.log # environments docker-compose.local.yml goldenpayerfsp -goldenpayeefsp \ No newline at end of file +goldenpayeefsp + +#vscode configs +.vscode/ +/init/.DS_Store +/.DS_Store diff --git a/LICENSE.md b/LICENSE.md index 26fb7bdd..40350591 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,10 +1,10 @@ # LICENSE -Copyright © 2017 Bill & Melinda Gates Foundation +Copyright © 2020 Mojaloop 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](http://www.apache.org/licenses/LICENSE-2.0). You may obtain a copy of the License at +The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 +(the "License") and you may not use these files except in compliance with the [License](http://www.apache.org/licenses/LICENSE-2.0). -[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) +You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](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](http://www.apache.org/licenses/LICENSE-2.0). diff --git a/README.md b/README.md index e67869a4..7d900098 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,14 @@ A diagram showing the logical architecture of the simulator in a test scenario c # Use +## Deploy with Helm and init containers (optional) +Three init containers, +- [onboard-hub-accounts](https://github.com/mojaloop/mojaloop-simulator/tree/master/init/onboard-hub-accounts) +- [onboard-central-ledger](https://github.com/mojaloop/mojaloop-simulator/tree/master/init/onboard-central-ledger) +- [onboard-msisdn-oracle](https://github.com/mojaloop/mojaloop-simulator/tree/master/init/onboard-msisdn-oracle) + +are provided for optional use and may make an automated deployment via Helm chart easier than otherwise. Please see the [example](docs/values-sims.example.yaml) config. + ## Pre-requisites 1. docker 2. docker-compose diff --git a/docs/values-sims.example.yaml b/docs/values-sims.example.yaml new file mode 100644 index 00000000..8682a9da --- /dev/null +++ b/docs/values-sims.example.yaml @@ -0,0 +1,139 @@ +prefix: "" + +# As per: +# https://github.com/mojaloop/helm/blob/4afd91b4d4c976e1f8d60495c677f1ba48b30192/mojaloop-simulator/values.yaml#L130-L134 +ingress: + ingressPathRewriteRegex: / + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + +defaults: + config: + backend: + env: + FEE_MULTIPLIER: "0.00" + schemeAdapter: + image: + tag: v10.6.3 + env: + VALIDATE_INBOUND_JWS: "true" + PEER_ENDPOINT: "interop-switch.huboperator.live" + JWS_SIGN: "true" + AUTO_ACCEPT_QUOTES: "true" + AUTO_ACCEPT_PARTY: "true" + EXPIRY_SECONDS: 30 + REQUEST_PROCESSING_TIMEOUT_SECONDS: 20 + USE_QUOTE_SOURCE_FSP_AS_TRANSFER_PAYEE_FSP: "true" + REJECT_TRANSFERS_ON_EXPIRED_QUOTES: "true" + ILP_SECRET: "Use2DwOwCea6VobuFScu3IcoEviS3Oth" + ingress: + enabled: true + hosts: + - "interop-switch.huboperator.live" + +simulators: + payerfsp: + config: + backend: # These are optional keys covering + rules: [] # rules-engine configured rules + schemeAdapter: + initContainers: + - name: onboard-hub-accounts + image: &hub_account_onboard_image mojaloop/onboard-hub-accounts:v11.0.3 + env: + - name: AUTH_BEARER_TOKEN + value: "6e35ccb3-ec22-51c9-b768-d12c3d289442" + - name: HOST_CENTRAL_LEDGER + value: "http://centralledger-service.ext-svcs.svc.cluster.local" + - name: HUB_OPERATOR_NAME + value: "hub_operator" + - name: ACCOUNTS + value: '[{ "type": "HUB_MULTILATERAL_SETTLEMENT", "currency": "USD" },{ "type": "HUB_RECONCILIATION", "currency": "USD" }]' + - name: onboard-central-ledger + image: ¢ral_ledger_onboard_image mojaloop/onboard-central-ledger:v11.0.3 + env: + - name: AUTH_BEARER_TOKEN + value: "6e35ccb3-ec22-51c9-b768-d12c3d289442" + - name: DFSP_CALLBACK_URL + value: "https://dfsp.huboperator.live:9999/payerfsp" + - name: DFSP_CURRENCY + value: "USD" + - name: DFSP_NAME + value: "payerfsp" + - name: FUNDS_IN_PREPARE_AMOUNT + value: "10000" + - name: HOST_CENTRAL_LEDGER + value: "http://centralledger-service.ext-svcs.svc.cluster.local" + - name: HUB_OPERATOR_NAME + value: "hub_operator" + - name: INITIAL_POSITION + value: "0" + - name: NET_DEBIT_CAP + value: "10000" + - name: NDC_ADJUSTMENT_EMAIL + value: "hub.operator@domain.com" + - name: NDC_THRESHOLD_BREACH_EMAIL + value: "hub.operator@domain.com" + - name: SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL + value: "hub.operator@domain.com" + - name: onboard-msisdn-oracle + image: &msisdn_onboard_image mojaloop/onboard-msisdn-oracle:v11.0.3 + env: + - name: HOST_PATHFINDER_ORACLE + value: pathfinder-oracle.ext-svcs.svc.cluster.local + - name: MSISDN_LIST + value: '[{"MSISDN":"12345678901","currency":"USD"}]' + - name: DFSP_NAME + value: payerfsp + + payeefsp: + config: + schemeAdapter: + initContainers: + - name: onboard-hub-accounts + image: *hub_account_onboard_image + env: + - name: AUTH_BEARER_TOKEN + value: "6e35ccb3-ec22-51c9-b768-d12c3d289442" + - name: HOST_CENTRAL_LEDGER + value: "http://centralledger-service.ext-svcs.svc.cluster.local" + - name: HUB_OPERATOR_NAME + value: "hub_operator" + - name: ACCOUNTS + value: '[{ "type": "HUB_MULTILATERAL_SETTLEMENT", "currency": "XOF" },{ "type": "HUB_RECONCILIATION", "currency": "XOF" }]' + - name: onboard-central-ledger + image: *central_ledger_onboard_image + env: + - name: AUTH_BEARER_TOKEN + value: "6e35ccb3-ec22-51c9-b768-d12c3d289442" + - name: DFSP_CALLBACK_URL + value: "https://dfsp.huboperator.live:9999/payeefsp" + - name: DFSP_CURRENCY + value: "XOF" + - name: DFSP_NAME + value: "payeefsp" + - name: FUNDS_IN_PREPARE_AMOUNT + value: "10000" + - name: HOST_CENTRAL_LEDGER + value: "http://centralledger-service.ext-svcs.svc.cluster.local" + - name: HUB_OPERATOR_NAME + value: "hub_operator" + - name: INITIAL_POSITION + value: "0" + - name: NET_DEBIT_CAP + value: "10000" + - name: NDC_ADJUSTMENT_EMAIL + value: "hub.operator@domain.com" + - name: NDC_THRESHOLD_BREACH_EMAIL + value: "hub.operator@domain.com" + - name: SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL + value: "hub.operator@domain.com" + - name: onboard-msisdn-oracle + image: *msisdn_onboard_image + env: + - name: HOST_PATHFINDER_ORACLE + value: pathfinder-oracle.ext-svcs.svc.cluster.local + - name: MSISDN_LIST + value: '[{"MSISDN":"23456789012","currency":"USD"}]' + - name: DFSP_NAME + value: payeefsp diff --git a/helm/.gitignore b/helm/.gitignore deleted file mode 100644 index 9cc46ef1..00000000 --- a/helm/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# This way you can maintain a values-test.yaml in this repo for testing your changes to the chart, -# without accidentally including it in a packaged chart. -values-test.yaml diff --git a/helm/.helmignore b/helm/.helmignore deleted file mode 100644 index b7ece505..00000000 --- a/helm/.helmignore +++ /dev/null @@ -1,25 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj - -# This way you can maintain a values-test.yaml in this repo for testing your changes to the chart, -# without accidentally including it in a packaged chart. -values-test.yaml diff --git a/helm/Chart.yaml b/helm/Chart.yaml deleted file mode 100644 index 204a1729..00000000 --- a/helm/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -appVersion: "1.0" -description: Helm Chart for the Mojaloop (SDK based) Simulator -name: mojaloop-simulator -version: 2.0.0 diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl deleted file mode 100644 index 090eca39..00000000 --- a/helm/templates/_helpers.tpl +++ /dev/null @@ -1,32 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "mojaloop-simulator.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "mojaloop-simulator.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "mojaloop-simulator.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/helm/templates/config-jws-public-keys.yaml b/helm/templates/config-jws-public-keys.yaml deleted file mode 100644 index 4284d1c4..00000000 --- a/helm/templates/config-jws-public-keys.yaml +++ /dev/null @@ -1,26 +0,0 @@ -{{- if .Values.simulators }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: sim-jws-public-keys - labels: - app: sim - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -data: - {{- range $name, $customConfig := .Values.simulators }} - {{- $config := merge $customConfig $.Values.defaults }} - {{- if and (eq ($config.config.schemeAdapter.env.VALIDATE_INBOUND_JWS | upper) "TRUE") (not $config.config.schemeAdapter.secrets.jws.pubKeyConfigMapName) }} - {{- if eq $config.config.schemeAdapter.secrets.jws.publicKey "" }} - {{- fail (printf "INBOUND_JWS enabled and jws public key not specified for '%s'. You need to specify %s.schemeAdapter.secrets.jws.publicKey or %s.schemeAdapter.secrets.jws.pubKeyConfigMapName." $name $name $name) }} - {{- end }} - {{ $name }}.pem: |- -{{ $config.config.schemeAdapter.secrets.jws.publicKey | indent 4 }} - {{- end }} - {{- end }} - {{- range $name, $key := .Values.sharedJWSPubKeys }} - {{ $name }}.pem: |- -{{ $key | indent 4 }} - {{- end }} -{{- end }} diff --git a/helm/templates/config-rules.yaml b/helm/templates/config-rules.yaml deleted file mode 100644 index 332504b6..00000000 --- a/helm/templates/config-rules.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- range $name, $customConfig := .Values.simulators }} -{{- $config := merge $customConfig $.Values.defaults }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: sim-{{ $name }}-rules - labels: - app: sim-{{ $name }} - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -data: - rules.json: {{ $config.config.backend.rules | quote }} ---- -{{- end }} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml deleted file mode 100644 index 77f8131d..00000000 --- a/helm/templates/deployment.yaml +++ /dev/null @@ -1,259 +0,0 @@ -{{- range $name, $customConfig := .Values.simulators }} -{{- $config := merge $customConfig $.Values.defaults }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: sim-{{ $name }}-scheme-adapter - labels: - app: sim-{{ $name }}-scheme-adapter - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -spec: - replicas: {{ $config.replicaCount }} - selector: - matchLabels: - app: sim-{{ $name }}-scheme-adapter - release: {{ $.Release.Name }} - template: - metadata: - labels: - app: sim-{{ $name }}-scheme-adapter - release: {{ $.Release.Name }} - spec: - volumes: - {{- if eq ($config.config.schemeAdapter.env.JWS_SIGN | upper) "TRUE" }} - - name: jws-private-key - secret: - {{- if $config.config.schemeAdapter.secrets.jws.privKeySecretName }} - secretName: {{ $config.config.schemeAdapter.secrets.jws.privKeySecretName }} - {{- else }} - secretName: sim-{{ $name }}-jws-priv-key - {{- end }} - {{- end }} - - name: jws-public-keys - configMap: - {{- if $config.config.schemeAdapter.secrets.jws.publicKeyConfigMapName }} - name: {{ $config.config.schemeAdapter.secrets.jws.publicKeyConfigMapName }} - {{- else }} - name: sim-jws-public-keys - {{- end }} - {{- if $config.config.schemeAdapter.secrets.sim_tls_secrets_name }} - - name: tls-secrets - secret: - secretName: {{ $config.config.schemeAdapter.secrets.sim_tls_secrets_name }} - {{- end }} - {{- if $config.config.schemeAdapter.initContainers }} - initContainers: -{{ $config.config.schemeAdapter.initContainers | toYaml | indent 6 }} - {{- end }} - containers: - - name: scheme-adapter - image: "{{ $config.config.schemeAdapter.image.repository }}:{{ $config.config.schemeAdapter.image.tag }}" - imagePullPolicy: {{ $config.config.schemeAdapter.image.pullPolicy }} - ports: - - name: inboundapi - containerPort: 4000 - protocol: TCP - - name: outboundapi - containerPort: 4001 - protocol: TCP - {{- if $config.config.schemeAdapter.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: / - port: 4001 - scheme: HTTP -{{ $config.config.backend.readinessProbe | toYaml | indent 10 -}} - {{- end }} - {{- if $config.config.schemeAdapter.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: / - port: 4001 - scheme: HTTP -{{ $config.config.backend.livenessProbe | toYaml | indent 10 -}} - {{- end }} - volumeMounts: - - name: jws-public-keys - mountPath: {{ $config.config.schemeAdapter.env.JWS_VERIFICATION_KEYS_DIRECTORY }} - {{- if eq ($config.config.schemeAdapter.env.JWS_SIGN | upper) "TRUE" }} - - name: jws-private-key - mountPath: "/jwsSigningKey/" - {{- end }} - {{- if $config.config.schemeAdapter.secrets.sim_tls_secrets_name }} - - name: tls-secrets - mountPath: "/secrets/" - {{- end }} - env: - - name: CACHE_HOST - value: {{ printf "sim-%s-cache" $name | quote }} - - name: BACKEND_ENDPOINT - value: {{ printf "sim-%s-backend:3000" $name }} - - name: DFSP_ID - value: {{ $name | quote }} - {{- range $k, $v := $config.config.schemeAdapter.env }} - - name: {{ $k }} - value: {{ $v | quote }} - {{- end }} - resources: -{{ toYaml $config.config.schemeAdapter.resources | indent 10 }} - imagePullSecrets: - - name: {{ $config.config.imagePullSecretName }} - {{- with $config.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with $config.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with $config.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} - {{- end }} - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: sim-{{ $name }}-backend - labels: - app: sim-{{ $name }}-backend - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -spec: - replicas: {{ $config.replicaCount }} - selector: - matchLabels: - app: sim-{{ $name }}-backend - release: {{ $.Release.Name }} - template: - metadata: - labels: - app: sim-{{ $name }}-backend - release: {{ $.Release.Name }} - spec: - {{- if $config.config.backend.initContainers }} - initContainers: -{{ $config.config.backend.initContainers | toYaml | indent 6 }} - {{- end }} - containers: - - name: backend - image: "{{ $config.config.backend.image.repository }}:{{ $config.config.backend.image.tag }}" - imagePullPolicy: {{ $config.config.backend.image.pullPolicy }} - ports: - - name: simapi - containerPort: 3000 - protocol: TCP - - name: reportapi - containerPort: 3002 - protocol: TCP - - name: testapi - containerPort: 3003 - protocol: TCP - {{- if $config.config.backend.readinessProbe.enabled }} - readinessProbe: - httpGet: - path: / - port: 3000 - scheme: HTTP -{{ $config.config.backend.readinessProbe | toYaml | indent 10 -}} - {{- end }} - {{- if $config.config.backend.livenessProbe.enabled }} - livenessProbe: - httpGet: - path: / - port: 3000 - scheme: HTTP -{{ $config.config.backend.livenessProbe | toYaml | indent 10 -}} - {{- end }} - env: - - name: OUTBOUND_ENDPOINT - value: "http://sim-{{ $name }}-scheme-adapter:{{ $config.config.schemeAdapter.env.OUTBOUND_LISTEN_PORT }}" - - name: SCHEME_NAME - value: {{ $name | quote }} - - name: DFSP_ID - value: {{ $name | quote }} - {{- range $k, $v := $config.config.backend.env }} - - name: {{ $k }} - value: {{ $v | quote }} - {{- end }} - resources: -{{ toYaml $config.config.backend.resources | indent 10 }} - volumeMounts: - - name: sim-rules - mountPath: /rules/ - volumes: - - name: sim-rules - configMap: - name: sim-{{ $name }}-rules - imagePullSecrets: - - name: {{ $config.config.imagePullSecretName }} - {{- with $config.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with $config.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with $config.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} - {{- end }} ---- -{{- if $config.config.cache.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: sim-{{ $name }}-cache - labels: - app: sim-{{ $name }}-cache - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -spec: - replicas: {{ $config.replicaCount }} - selector: - matchLabels: - app: sim-{{ $name }}-cache - release: {{ $.Release.Name }} - template: - metadata: - labels: - app: sim-{{ $name }}-cache - release: {{ $.Release.Name }} - spec: - containers: - - name: cache - image: "{{ $config.config.cache.image.repository }}:{{ $config.config.cache.image.tag }}" - imagePullPolicy: {{ $config.config.cache.image.pullPolicy }} - ports: - - name: redis - containerPort: 6379 - protocol: TCP - {{- if $config.config.cache.livenessProbe.enabled }} - livenessProbe: -{{ $config.config.backend.livenessProbe | toYaml | indent 10 -}} - exec: - command: - - sh - - -c - - redis-cli ping {{ $config.config.cache.livenessProbe.timeoutSeconds }} - {{- end }} - {{- if $config.config.cache.readinessProbe.enabled}} - readinessProbe: -{{ $config.config.backend.readinessProbe | toYaml | indent 10 -}} - exec: - command: - - sh - - -c - - redis-cli ping {{ $config.config.cache.readinessProbe.timeoutSeconds }} - {{- end }} - resources: -{{ toYaml $config.config.cache.resources | indent 12 }} ---- -{{- end }} -{{ end }} diff --git a/helm/templates/horizontalpodautoscaler.yaml b/helm/templates/horizontalpodautoscaler.yaml deleted file mode 100644 index 53dc3272..00000000 --- a/helm/templates/horizontalpodautoscaler.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- range $name, $customConfig := .Values.simulators }} -{{- $config := merge $customConfig $.Values.defaults }} -{{- if $config.config.schemeAdapter.scale.enabled }} -apiVersion: autoscaling/v2beta2 -kind: HorizontalPodAutoscaler -metadata: - name: sim-{{ $name }}-scheme-adapter - labels: - app: sim-{{ $name }}-scheme-adapter - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: sim-{{ $name }}-scheme-adapter -{{ $config.config.schemeAdapter.scale.spec | toYaml | indent 2 }} ---- -{{- end }} -{{ end }} diff --git a/helm/templates/ingress.yaml b/helm/templates/ingress.yaml deleted file mode 100644 index d20a8dc5..00000000 --- a/helm/templates/ingress.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{ if .Values.simulators }} -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: simulators - labels: - app: simulators - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -{{- with .Values.ingress.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: - rules: - {{- range $name, $customConfig := .Values.simulators }} - {{- $config := merge $customConfig $.Values.defaults }} - {{- if $config.ingress.enabled -}} - {{- range $host := $config.ingress.hosts }} - - host: {{ $host }} - http: - paths: - - path: /sim/{{ $name }}/outbound{{ if $.Values.ingress.modernIngressController }}(.*){{ end }} - backend: - serviceName: sim-{{ $name }}-scheme-adapter - servicePort: outboundapi - - path: /sim/{{ $name }}/inbound{{ if $.Values.ingress.modernIngressController }}(.*){{ end }} - backend: - serviceName: sim-{{ $name }}-scheme-adapter - servicePort: inboundapi - - path: /sim/{{ $name }}/test{{ if $.Values.ingress.modernIngressController }}(.*){{ end }} - backend: - serviceName: sim-{{ $name }}-backend - servicePort: testapi - {{- end }} - {{- end }} - {{- end }} ---- -{{ end }} diff --git a/helm/templates/secret.yaml b/helm/templates/secret.yaml deleted file mode 100644 index 16ddaea6..00000000 --- a/helm/templates/secret.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- range $name, $customConfig := .Values.simulators }} -{{- $config := merge $customConfig $.Values.defaults }} -{{- if eq ($config.config.schemeAdapter.env.JWS_SIGN | upper) "TRUE" }} -apiVersion: v1 -kind: Secret -metadata: - name: sim-{{ $name }}-jws-priv-key - labels: - app: sim-{{ $name }} - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -data: - # Note that due to a bug with helm 2.91 the `required` function in combination with a missing key - # will not work in place of this if statement. - {{- if eq $config.config.schemeAdapter.secrets.jws.privateKey "" }} - {{ fail (printf "JWS_SIGN enabled- JWS private key required for %s. You need to specify %s.schemeAdapter.secrets.jws.privateKey." $name $name) }} - {{- end }} - "private.key": {{ $config.config.schemeAdapter.secrets.jws.privateKey | b64enc }} ---- -{{- end }} -{{- end }} diff --git a/helm/templates/service.yaml b/helm/templates/service.yaml deleted file mode 100644 index 1c096929..00000000 --- a/helm/templates/service.yaml +++ /dev/null @@ -1,77 +0,0 @@ -{{- range $name, $customConfig := .Values.simulators }} -{{- $config := merge $customConfig $.Values.defaults }} -apiVersion: v1 -kind: Service -metadata: - name: sim-{{ $name }}-backend - labels: - app: sim-{{ $name }}-backend - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -spec: - type: ClusterIP - ports: - - port: 3000 - protocol: TCP - name: simapi - targetPort: simapi - - port: 3002 - protocol: TCP - name: reportapi - targetPort: reportapi - - port: 3003 - protocol: TCP - name: testapi - targetPort: testapi - selector: - app: sim-{{ $name }}-backend - release: {{ $.Release.Name }} ---- -apiVersion: v1 -kind: Service -metadata: - name: sim-{{ $name }}-scheme-adapter - labels: - app: sim-{{ $name }}-scheme-adapter - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -spec: - type: ClusterIP - ports: - - port: 4000 - protocol: TCP - name: inboundapi - targetPort: inboundapi - - port: 4001 - protocol: TCP - name: outboundapi - targetPort: outboundapi - selector: - app: sim-{{ $name }}-scheme-adapter - release: {{ $.Release.Name }} ---- -{{- if $config.config.cache.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: sim-{{ $name }}-cache - labels: - app: sim-{{ $name }}-cache - chart: {{ template "mojaloop-simulator.chart" $ }} - release: {{ $.Release.Name }} - heritage: {{ $.Release.Service }} -spec: - type: ClusterIP - ports: - - port: 6379 - protocol: TCP - name: redis - targetPort: redis - selector: - app: sim-{{ $name }}-cache - release: {{ $.Release.Name }} -{{- end }} ---- -{{ end }} diff --git a/helm/values.yaml b/helm/values.yaml deleted file mode 100644 index 64a0cc22..00000000 --- a/helm/values.yaml +++ /dev/null @@ -1,429 +0,0 @@ -# Default values for mojaloop-simulator. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# Usage: -# Add simulators to the simulators object. The following example will create two simulators, -# 'payerfsp' and 'payeefsp' that will be created with the default values available lower in this -# file. -# -# simulators: -# payerfsp: {} -# payeefsp: {} -# -# The default values can be overridden for all sims by modifying mojaloop-simulator.defaults in -# your parent chart. They can also be overriden per-simulator. The following example will result in -# a payerfsp without a cache and a payeefsp with a cache. -# -# simulators: -# payerfsp: -# config: -# cache: -# enabled: false -# payeefsp: {} - -# TODO & notes: -# * do the port _numbers_ matter at all? Can we get rid of them? -# * for Mowali, how are JWS and TLS secrets being set up? -# * support arbitrary init containers + config (that might just be config that goes into defaults -# or something?). Supply all config and volumes to the init containers. -# * create some test containers -# * parametrise imagePullSecretName (global? like https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters) -# * generate JWS private/public keys, so the user does not need to supply keys at all. -# * generate public key from private, so the user only needs to supply private keys for each sim? -# (_might_ be possible with a job or init container or similar). -# * support mTLS auto-cert generation -# * probably eliminate all config that shouldn't actually be changed by a user, e.g. -# JWS_VERIFICATION_KEYS_DIRECTORY. That's a good configuration option to have for other contexts, -# such as running the sim locally or in docker-compose but in this context it's _an -# implementation detail_. The chart user should not have to worry about it, and we should not -# have to test the effect of changing it. -# Also -# INBOUND_LISTEN_PORT -# OUTBOUND_LISTEN_PORT -# * make ingress more generic- do not preconfigure annotations -# * think about labels a little more carefully- the app should probably always be "mojaloop-simulator" -# * add config map and hashes to the deployments so that a configmap change triggers a rolling -# update -# * support JWS public keys for other entities. Add a note in the documentation that they must map -# directly to the value that will be received in the FSPIOP-Source (check this is correct) -# * update labels to be compliant. E.g. app.kubernetes.io/name or whatever -# * rename ".Values.defaults.config" as it's pretty a useless name -# * support arbitrary sidecars? -# * use the redis subchart? https://github.com/bitnami/charts/tree/master/bitnami/redis -# - this would mean a single instance of redis (probably good) -# - might need to have the simulators use separate databases per simulator, or prefix all of -# their keys with their own name, or something -# * allow the user to optionally specify the namespace, with the caveat that that namespace will -# need to be created manually before the release is deployed. There may be a horrible hack (which -# I have not tried) whereby all templates are moved to a different directory, say ./xtemplates, -# then all are imported using {{ .Files.Glob }} and {{ .Files.Get }} then templated into a single -# amazing template with {{ template }}. At the top of this template goes a namespace. The -# consequence of this is that the namespace is created first, enabling this beautiful pattern. -# Remember, with great power comes great responsibility. (In other words, we probably have a -# responsibility to _not_ do this). -# * should redis be a statefulset? optionally? what does the bitnami chart do? -# * move labels into helpers -# * autogenerate ILP stuff? -# * defaults.resources looks like it's used nowhere- check this and remove it as appropriate -# * look for references to replicaCount in the charts/values. Is it set, or whatever? -# * scale Redis -# * changing JWS_SIGNING_KEY_PATH currently breaks the chart because it's nastily hard-coded. It -# should be possible to use the Spring filepath functions to avoid this. Similarly, changing -# RULES_FILE will have a similar effect. Alternatively, make these unconfigured by default. I.e. -# comment them out, hard-code them and add a warning to the user in the config. (Is there a -# scenario where the user should want to configure them? I don't think so..). -# (https://masterminds.github.io/sprig/paths.html) -# * put sim inbound API on port 80 -# * supply more documentation, especially a range of examples, and preferably documentation that is -# executable -# * share configmaps, secrets with init containers -# * share an emptyDir volume between init containers and main containers -# * allow init containers to create secrets and put them on persistent volumes, or emptyDirs, then -# allow main containers to access those -# * do not put environment variables in configmaps, instead put them straight into the deployments. -# This makes the deployment much easier to manage. -# * Remember, labels are _for_ identifying stuff. So labels should probably be like "release" -# (.Release.Name or similar) "chart" (.Chart.Name or similar) "simulator" (e.g. payerfsp, -# payeefsp) "sim-component" (e.g. backend, scheme-adapter, cache) -# * can _probably_ remove port numbers from services to simplify chart (although perhaps not? try -# to port-forward with a named port instead of a numbered port?) - - -simulators: - # Every key added to this `simulators` object will be a simulator that takes on the default - # config below. The default is deliberately left empty so nothing is deployed by default. - # payerfsp: {} - # payeefsp: {} - -defaultProbes: &defaultProbes - livenessProbe: - enabled: true - initialDelaySeconds: 3 - periodSeconds: 30 - timeoutSeconds: 10 - successThreshold: 1 - failureThreshold: 3 - readinessProbe: - enabled: true - initialDelaySeconds: 3 - periodSeconds: 5 - timeoutSeconds: 5 - successThreshold: 1 - failureThreshold: 3 - -ingress: - annotations: {} - # Set this to true if you're using nginx ingress controller >= v0.22.0. - # This affects the way your rewrite target will work. - # For more information see "Breaking changes" here: - # https://github.com/kubernetes/ingress-nginx/blob/master/Changelog.md#0220 - modernIngressController: true - -# If you enable JWS validation and intend to communicate via a switch you will almost certainly -# want to put your switch JWS public key in this array. The name of the property in this object -# will correspond directly to the name of the signing key (e.g., in the example below, -# `switch.pem`). Do not include the `.pem` extension, this will be added for you. The scheme -# adapter will use the FSPIOP-Source header content to identify the relevant signing key to use. -# The below example assumes your switch will use `FSPIOP-Source: switch`. If instead, for example, -# your switch is using `FSPIOP-Source: peter` you will need a property `peter` in the following -# object. Do not add the public keys of your simulators to this object. Instead, put them in -# `mojaloop-simulator.simulators.$yourSimName.config.schemeAdapter.secrets.jws.publicKey`. -sharedJWSPubKeys: - # switch: |- - # -----BEGIN PUBLIC KEY----- - # blah blah blah - # -----END PUBLIC KEY----- - -defaults: &defaults - # Changes to this object in the parent chart, for example 'mojaloop-simulator.defaults' will be - # applied to all simulators deployed by this child chart. - config: - imagePullSecretName: dock-casa-secret - - cache: - enabled: true - image: - repository: redis - tag: 5.0.4-alpine - pullPolicy: Always - <<: *defaultProbes - - schemeAdapter: - secrets: - jws: - # Use the privKeySecretName field if you would like to supply a JWS private key external - # to this chart. - # For example, if you create a private key called `sim-payerfsp-jws-signing-key` external - # to this chart, you would supply `privKeySecretName: sim-payerfsp-jws-signing-key` here. - # These fields will take precedence over `privateKey` and `publicKey` below. - # This field is best supplied per-simulator, however it's here for documentation - # purposes. - privKeySecretName: {} - # TODO: update `privKeySecretName` above to contain both a name and a key in the secret. - # Add documentation on usage. - # privKeySecret: {} - # name: - # key: - # - # The `pubKeyConfigMapName` field allows you to supply a ConfigMap containing JWS public - # keys external to this release, and have this release reference that ConfigMap to - # populate JWS public keys. The format of this ConfigMap must be as described for - # `sharedJWSPubKeys`, a map with one key per FSP/simulator corresponding to the - # FSPIOP-Source header that will be supplied by that FSP/simulator. - pubKeyConfigMapName: {} - # Supply per-simulator private and public keys here: - privateKey: '' - publicKey: '' - image: - repository: mojaloop/sdk-scheme-adapter - tag: v8.6.1 - pullPolicy: Always - <<: *defaultProbes - - # These will be supplied directly to the init containers array in the deployment for the - # scheme adapter. They should look exactly as you'd declare them inside the deployment. - # Example: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#init-containers-in-use - initContainers: {} - - scale: - enabled: false - spec: - minReplicas: 1 - maxReplicas: 10 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 80 - - env: - # This option is presented for consistency with the .env file. However, for the purposes of this chart, this port is _not_ configurable. - INBOUND_LISTEN_PORT: "4000" - - # This option is presented for consistency with the .env file. However, for the purposes of this chart, this port is _not_ configurable. - OUTBOUND_LISTEN_PORT: "4001" - - # Enable mutual TLS authentication. Useful when not running in a secure - # environment, i.e. when you're running it locally against your own implementation. - MUTUAL_TLS_ENABLED: "false" - - # Enable JWS verification and signing - VALIDATE_INBOUND_JWS: "false" - JWS_SIGN: "false" - - # applicable only if VALIDATE_INBOUND_JWS is "true" - # allows disabling of validation on incoming PUT /parties/{idType}/{idValue} requests - VALIDATE_INBOUND_PUT_PARTIES_JWS: "true" - - # applicable only if JWS_SIGN is "true" - # allows disabling of signing on outgoing PUT /parties/{idType}/{idValue} requests - JWS_SIGN_PUT_PARTIES: "true" - - # Path to JWS signing key (private key of THIS DFSP) - JWS_SIGNING_KEY_PATH: "/jwsSigningKey/private.key" # TODO: do not configure- will break the chart - JWS_VERIFICATION_KEYS_DIRECTORY: "/jwsVerificationKeys" - - # Location of certs and key required for TLS - IN_CA_CERT_PATH: "./secrets/cacert.pem" - IN_SERVER_CERT_PATH: "./secrets/servercert.pem" - IN_SERVER_KEY_PATH: "./secrets/serverkey.pem" - - OUT_CA_CERT_PATH: "./secrets/cacert.pem" - OUT_CLIENT_CERT_PATH: "./secrets/servercert.pem" - OUT_CLIENT_KEY_PATH: "./secrets/serverkey.pem" - - # The number of space characters by which to indent pretty-printed logs. If set to zero, log events - # will each be printed on a single line. - LOG_INDENT: "0" - - # REDIS CACHE CONNECTION - # CACHE_HOST: "" # Default is parametrised, but it's possible to override this - CACHE_PORT: "6379" - - # Switch or DFSP system under test Mojaloop API endpoint - # The option 'PEER_ENDPOINT' has no effect if the remaining three options 'ALS_ENDPOINT', 'QUOTES_ENDPOINT', 'TRANSFERS_ENDPOINT' are specified. - # Do not include the protocol, i.e. http. - PEER_ENDPOINT: "mojaloop-switch" - # ALS_ENDPOINT="mojaloop-switch-als" - # QUOTES_ENDPOINT="mojaloop-switch-quotes" - # TRANSFERS_ENDPOINT="mojaloop-switch-transfers" - - # This value specifies the endpoint the scheme adapter expects to communicate with the - # backend on. Do not include the protocol, i.e. http. - # You're very likely to break the functioning of this chart if you configure the following - # value. - # BACKEND_ENDPOINT: "localhost:3000" - - # FSPID of this DFSP - # Commented by default- you're likely to break the chart if you configure this value. - # DFSP_ID: "mojaloop-sdk" - - # Secret used for generation and verification of secure ILP - ILP_SECRET: "Quaixohyaesahju3thivuiChai5cahng" - - # expiry period in seconds for quote and transfers issued by the SDK - EXPIRY_SECONDS: "60" - - # if set to false the SDK will not automatically accept all returned quotes - # but will halt the transfer after a quote response is received. A further - # confirmation call will be required to complete the final transfer stage. - AUTO_ACCEPT_QUOTES: "false" - - # if set to false the SDK will not automatically accept a resolved party - # but will halt the transer after a party lookup response is received. A further - # confirmation call will be required to progress the transfer to quotes state. - AUTO_ACCEPT_PARTY: "false" - - # when set to true, when sending money via the outbound API, the SDK will use the value - # of FSPIOP-Source header from the received quote response as the payeeFsp value in the - # transfer prepare request body instead of the value received in the payee party lookup. - # This behaviour should be enabled when the SDK user DFSP is in a forex enabled switch - # ecosystem and expects quotes and transfers to be rerouted by the switch to forex - # entities i.e. forex providing DFSPs. Please see the SDK documentation and switch - # operator documentation for more information on forex use cases. - USE_QUOTE_SOURCE_FSP_AS_TRANSFER_PAYEE_FSP: "false" - - # set to true to validate ILP, otherwise false to ignore ILP - CHECK_ILP: "true" - - # set to true to enable test features such as request cacheing and retrieval endpoints - ENABLE_TEST_FEATURES: "true" - - # set to true to mock WSO2 oauth2 token endpoint - ENABLE_OAUTH_TOKEN_ENDPOINT: "false" - OAUTH_TOKEN_ENDPOINT_CLIENT_KEY: "test-client-key" - OAUTH_TOKEN_ENDPOINT_CLIENT_SECRET: "test-client-secret" - OAUTH_TOKEN_ENDPOINT_LISTEN_PORT: "6000" - - # WS02 Bearer Token specific to golden-fsp instance and environment - WS02_BEARER_TOKEN: "7718fa9b-be13-3fe7-87f0-a12cf1628168" - - # OAuth2 data used to obtain WSO2 bearer token - OAUTH_TOKEN_ENDPOINT: "" - OAUTH_CLIENT_KEY: "" - OAUTH_CLIENT_SECRET: "" - OAUTH_REFRESH_SECONDS: "3600" - - # Set to true to respect expirity timestamps - REJECT_EXPIRED_QUOTE_RESPONSES: "false" - REJECT_TRANSFERS_ON_EXPIRED_QUOTES: "false" - REJECT_EXPIRED_TRANSFER_FULFILS: "false" - - # Timeout for GET/POST/DELETE - PUT flow processing - REQUEST_PROCESSING_TIMEOUT_SECONDS: "30" - - # To allow transfer without a previous quote request, set this value to true. - # The incoming transfer request should consist of an ILP packet and a matching condition in this case. - # The fulfilment will be generated from the provided ILP packet, and must hash to the provided condition. - ALLOW_TRANSFER_WITHOUT_QUOTE: "false" - - INBOUND_MUTUAL_TLS_ENABLED: "false" - OUTBOUND_MUTUAL_TLS_ENABLED: "false" - - backend: - image: - repository: mojaloop/mojaloop-simulator - tag: v8.6.0-snapshot - pullPolicy: Always - <<: *defaultProbes - - # These will be supplied directly to the init containers array in the deployment for the - # backend. They should look exactly as you'd declare them inside the deployment. - # Example: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#init-containers-in-use - initContainers: {} - - # Supply JSON rules here as a string - # Example: - # rules: |- - # [ - # { - # "ruleId": 1, - # .. etc. - # } - # ] - rules: |- - [] - - env: - ##### Section for simulator backend container ##### - # This is the endpoint the backend expects to communicate with the scheme adapter on. - # Include the protocol, i.e. http. - # It's not configured by default in this chart as the default value is calculated in a - # template and configuring it is likely to break communication between the backend and the - # scheme adapter. - # OUTBOUND_ENDPOINT: "http://localhost:4001" # within the pod - - # Enable mutual TLS authentication. Useful when the simulator is not running in a managed - # environment, i.e. when you're running it locally against your own implementation. - MUTUAL_TLS_ENABLED: "false" - - # Enable server-only TLS; i.e. serve on HTTPS instead of HTTP. - HTTPS_ENABLED: "false" - - # Location of certs and key required for TLS - CA_CERT_PATH: ./secrets/cacert.pem - SERVER_CERT_PATH: ./secrets/servercert.pem - SERVER_KEY_PATH: ./secrets/serverkey.pem - - # The number of space characters by which to indent pretty-printed logs. If set to zero, log events - # will each be printed on a single line. - LOG_INDENT: "0" - - # The name of the sqlite log file. This probably doesn't matter much to the user, except that - # setting :memory: will use an in-memory sqlite db, which will be faster and not consume disk - # space. However, it will also mean that the logs will be lost once the container is stopped. - SQLITE_LOG_FILE: ./log.sqlite - - # The DFSPID of this simulator. The simulator will accept any requests routed to - # FSPIOP-Destination: $SCHEME_NAME. Other requests will be rejected. - # Not set in this chart as these are calculated in templates. Setting this values is likely - # to break expected functionality. - # SCHEME_NAME: golden - # DFSP_ID: golden - - # The name of the sqlite model database. If you would like to start the simulator with preloaded - # state you can use a preexisting file. If running in a container, you can mount a sqlite file as a - # volume in the container to preserve state between runs. - # Use MODEL_DATABASE: :memory: for an ephemeral in-memory database - MODEL_DATABASE: ./model.sqlite - - # The simulator can automatically add fees when generating quote responses. Use this - # variable to control the fee amounts added. e.g. for a transfer of 100 USD a FEE_MULTIPLIER of 0.1 - # reuslts in fees of USD 10 being applied to the quote response - FEE_MULTIPLIER: "0.05" - - # Specifies the location of a rules file for the simulator backend. Rules can be used to produce - # specific simulator behaviours in response to incoming requests that match certain conditions. - # e.g. a rule can be used to trigger NDC errors given transfers between certain limits. - RULES_FILE: /rules/rules.json - - ingress: - enabled: true - path: / - hosts: - - mojaloop-simulators.local - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - - resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - - nodeSelector: {} - - tolerations: [] - - affinity: {} diff --git a/init/onboard-central-ledger/.eslintrc.json b/init/onboard-central-ledger/.eslintrc.json new file mode 100644 index 00000000..2ad15fd8 --- /dev/null +++ b/init/onboard-central-ledger/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "airbnb-base", + "env": { + "node": true + } +} diff --git a/init/onboard-central-ledger/.gitignore b/init/onboard-central-ledger/.gitignore new file mode 100644 index 00000000..4c49bd78 --- /dev/null +++ b/init/onboard-central-ledger/.gitignore @@ -0,0 +1 @@ +.env diff --git a/init/onboard-central-ledger/Dockerfile b/init/onboard-central-ledger/Dockerfile new file mode 100644 index 00000000..c6db93b7 --- /dev/null +++ b/init/onboard-central-ledger/Dockerfile @@ -0,0 +1,28 @@ +FROM node:12.18.2-alpine as builder + +ARG CREATED +ARG SOURCE +ARG REVISION +ARG VERSION + +# See https://github.com/opencontainers/image-spec/blob/master/annotations.md#pre-defined-annotation-keys and https://github.com/opencontainers/image-spec/blob/master/spec.md for info +LABEL org.opencontainers.image.created=${CREATED} +LABEL org.opencontainers.image.url="https://mojaloop.io/" +LABEL org.opencontainers.image.source=${SOURCE} +LABEL org.opencontainers.image.version=${VERSION} +LABEL org.opencontainers.image.revision=${REVISION} +LABEL org.opencontainers.image.title="onboard-central-ledger" +LABEL org.opencontainers.image.authors="kamuela.franco@modusbox.com" +LABEL org.opencontainers.image.licenses="Apache-2.0" + +WORKDIR /opt/onboard-central-ledger +COPY package* *.js /opt/onboard-central-ledger/ + +RUN ["npm", "ci", "--production"] + +FROM node:12.18.2-alpine +WORKDIR /opt/onboard-central-ledger + +COPY --from=builder /opt/onboard-central-ledger . + +CMD ["node", "onboard-dfsp.js"] diff --git a/init/onboard-central-ledger/onboard-dfsp.js b/init/onboard-central-ledger/onboard-dfsp.js new file mode 100644 index 00000000..920f0099 --- /dev/null +++ b/init/onboard-central-ledger/onboard-dfsp.js @@ -0,0 +1,464 @@ +const uuid = require('uuid'); +const { + onboarding: { + sendRequest, + settlementIdFromHubAccounts, + getDfspAccounts, + addDfsp, + addInitialPositionAndLimits, + depositFunds, + addCallbackParticipantPut, + addCallbackParticipantPutError, + addCallbackParticipantPutBatch, + addCallbackParticipantPutBatchError, + addCallbackPartiesGet, + addCallbackPartiesPut, + addCallbackPartiesPutError, + addCallbackQuotes, + addCallbackTransferPost, + addCallbackTransferPut, + addCallbackTransferError, + setEmailNetDebitCapAdjustment, + setEmailSettlementTransferPositionChange, + setEmailNetDebitCapThresholdBreach, + }, +} = require('@mojaloop/finance-portal-lib'); + +function log(message) { + const timestamp = (new Date()).toISOString(); + // eslint-disable-next-line no-console + console.log(`[${timestamp}] ${message}`); +} + +log(`ENV: AUTH_BEARER_TOKEN:\t\t\t\t${process.env.AUTH_BEARER_TOKEN}`); +log(`ENV: DFSP_CALLBACK_URL:\t\t\t\t${process.env.DFSP_CALLBACK_URL}`); +log(`ENV: DFSP_CURRENCY:\t\t\t\t\t${process.env.DFSP_CURRENCY}`); +log(`ENV: DFSP_NAME:\t\t\t\t\t${process.env.DFSP_NAME}`); +log(`ENV: FUNDS_IN_PREPARE_AMOUNT:\t\t\t${process.env.FUNDS_IN_PREPARE_AMOUNT}`); +log(`ENV: HOST_CENTRAL_LEDGER:\t\t\t\t${process.env.HOST_CENTRAL_LEDGER}`); +log(`ENV: HUB_OPERATOR_NAME:\t\t\t\t${process.env.HUB_OPERATOR_NAME}`); +log(`ENV: INITIAL_POSITION:\t\t\t\t${process.env.INITIAL_POSITION}`); +log(`ENV: NDC_ADJUSTMENT_EMAIL:\t\t\t\t${process.env.NDC_ADJUSTMENT_EMAIL}`); +log(`ENV: NDC_THRESHOLD_BREACH_EMAIL:\t\t\t${process.env.NDC_THRESHOLD_BREACH_EMAIL}`); +log(`ENV: NET_DEBIT_CAP:\t\t\t\t\t${process.env.NET_DEBIT_CAP}`); +log(`ENV: SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL:\t${process.env.SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL}`); + +const amount = process.env.FUNDS_IN_PREPARE_AMOUNT; +const authToken = process.env.AUTH_BEARER_TOKEN; +const dfspCallbackUrl = process.env.DFSP_CALLBACK_URL; +const dfspCurrency = process.env.DFSP_CURRENCY; +const dfspName = process.env.DFSP_NAME; +const fspiopSource = process.env.HUB_OPERATOR_NAME; +const hostCentralLedger = process.env.HOST_CENTRAL_LEDGER; +const initialPosition = parseInt(process.env.INITIAL_POSITION, 10); +log(`LOC: initialPosition:\t\t\t\t${initialPosition}`); +const netDebitCap = parseInt(process.env.NET_DEBIT_CAP, 10); +log(`LOC: netDebitCap:\t\t\t\t\t${netDebitCap}`); +const ndcAdjustmentEmail = process.env.NDC_ADJUSTMENT_EMAIL; +const ndcThresholdBreachEmail = process.env.NDC_THRESHOLD_BREACH_EMAIL; +const settlementTransferPositionChangeEmail = process.env.SETTLEMENT_TRANSFER_POSITION_CHANGE_EMAIL; + +async function onboardDfsp() { + try { + log('EXE: INIT: sendRequest->addDfsp'); + const response = await sendRequest(addDfsp({ + dfspName, + dfspCurrency, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addDfsp'); + } else { + const error = await response.json(); + // Allow re-registering of the same DFSP name and currency + if (response.status === 400 && error.errorInformation.errorCode === '3000' + && /already/.test(error.errorInformation.errorDescription)) { + log(`EXE: FAIL: sendRequest->addDfsp:\t\t\t${JSON.stringify(error)}`); + log('EXE: INFO: Allowed failure:\t\t\t\tProceeding with next request'); + } else { + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addDfsp:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addInitialPositionAndLimits'); + const response = await sendRequest(addInitialPositionAndLimits({ + dfspName, + dfspCurrency, + netDebitCap, + initialPosition, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addInitialPositionAndLimits'); + } else { + const error = await response.json(); + // Allow re-registering + if (response.status === 500 && error.errorInformation.errorCode === '2001' + && /already/.test(error.errorInformation.errorDescription)) { + log(`EXE: FAIL: sendRequest->addInitialPositionAndLimits:\t${JSON.stringify(error)}`); + log('EXE: INFO: Allowed failure:\t\t\t\tProceeding with next request'); + } else { + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addInitialPositionAndLimits:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->getDfspAccounts'); + const response = await sendRequest(getDfspAccounts({ + dfspName, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + const dfspAccounts = await response.json(); + log('EXE: SUCC: sendRequest->getDfspAccounts'); + log(`LOC: dfspAccounts:\t\t\t\t\t${JSON.stringify(dfspAccounts)}`); + log('EXE: INIT: settlementAccountIdFromHubAccounts'); + const settlementAccountId = settlementIdFromHubAccounts(dfspAccounts, dfspCurrency); + log('EXE: SUCC: settlementAccountIdFromHubAccounts'); + log(`LOC: settlementAccountId:\t\t\t\t${settlementAccountId}`); + log('EXE: INIT: sendRequest->depositFunds'); + const innerResponse = await sendRequest(depositFunds({ + dfspName, + dfspCurrency, + amount, + transferId: uuid.v4(), + settlementAccountId, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (innerResponse.ok) { + log('EXE: SUCC: sendRequest->depositFunds'); + } else { + const innerError = await innerResponse.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(innerError)}`); + } + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + // Testing indicates this regex will match a settlementAccountIdFromHubAccounts error, but not a + // depositFunds error + if (/property/.test(message)) { + // So that a more specific failure can be logged + log(`EXE: FAIL: settlementAccountIdFromHubAccounts:\t${message}`); + } else { + log(`EXE: FAIL: sendRequest->depositFunds:\t\t${message}`); + } + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackParticipantPut'); + const response = await sendRequest(addCallbackParticipantPut({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackParticipantPut'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackParticipantPut:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackParticipantPutError'); + const response = await sendRequest(addCallbackParticipantPutError({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackParticipantPutError'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackParticipantPutError:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackParticipantPutBatch'); + const response = await sendRequest(addCallbackParticipantPutBatch({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatch'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatch:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackParticipantPutBatchError'); + const response = await sendRequest(addCallbackParticipantPutBatchError({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackParticipantPutBatchError'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackParticipantPutBatchError:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackPartiesGet'); + const response = await sendRequest(addCallbackPartiesGet({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackPartiesGet'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackPartiesGet:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackPartiesPut'); + const response = await sendRequest(addCallbackPartiesPut({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackPartiesPut'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackPartiesPut:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackPartiesPutError'); + const response = await sendRequest(addCallbackPartiesPutError({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackPartiesPutError'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackPartiesPutError:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackQuotes'); + const response = await sendRequest(addCallbackQuotes({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackQuotes'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackQuotes:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackTransferPost'); + const response = await sendRequest(addCallbackTransferPost({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackTransferPost'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackTransferPost:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackTransferPut'); + const response = await sendRequest(addCallbackTransferPut({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackTransferPut'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackTransferPut:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->addCallbackTransferError'); + const response = await sendRequest(addCallbackTransferError({ + dfspName, + dfspCallbackUrl, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->addCallbackTransferError'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->addCallbackTransferError:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->setEmailNetDebitCapAdjustment'); + const response = await sendRequest(setEmailNetDebitCapAdjustment({ + dfspName, + email: ndcAdjustmentEmail, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->setEmailNetDebitCapAdjustment'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->setEmailNetDebitCapAdjustment:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->setEmailSettlementTransferPositionChange'); + const response = await sendRequest(setEmailSettlementTransferPositionChange({ + dfspName, + email: settlementTransferPositionChangeEmail, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->setEmailSettlementTransferPositionChange'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->setEmailSettlementTransferPositionChange:\t${message}`); + process.exitCode = 1; + return; + } + + try { + log('EXE: INIT: sendRequest->setEmailNetDebitCapThresholdBreach'); + const response = await sendRequest(setEmailNetDebitCapThresholdBreach({ + dfspName, + email: ndcThresholdBreachEmail, + authToken, + hostCentralLedger, + fspiopSource, + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->setEmailNetDebitCapThresholdBreach'); + } else { + const error = await response.json(); + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->setEmailNetDebitCapThresholdBreach:\t${message}`); + process.exitCode = 1; + } +} + +onboardDfsp(); diff --git a/init/onboard-central-ledger/package-lock.json b/init/onboard-central-ledger/package-lock.json new file mode 100644 index 00000000..03bd694f --- /dev/null +++ b/init/onboard-central-ledger/package-lock.json @@ -0,0 +1,1751 @@ +{ + "name": "onboard-central-ledger", + "version": "11.0.3", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@mojaloop/finance-portal-lib": { + "version": "0.0.19-snapshot", + "resolved": "https://registry.npmjs.org/@mojaloop/finance-portal-lib/-/finance-portal-lib-0.0.19-snapshot.tgz", + "integrity": "sha512-mFJ0Ewt7yPob+38sZWIf6MQ8crW282lzWROVnfEGWDmLZWuVSlZA9qqrhveD+ia7hys/sBItBPNBmRCov7DfWw==", + "requires": { + "abort-controller": "^3.0.0", + "big.js": "5.2.2", + "node-fetch": "2.3.0", + "uuid": "3.3.2", + "xml-js": "1.6.8" + }, + "dependencies": { + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "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, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.2.0.tgz", + "integrity": "sha512-B3BtEyaDKC5MlfDa2Ha8/D6DsS4fju95zs0hjS3HdGazw+LNayai38A25qMppK37wWGWNYSPOR6oYzlz5MHsRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.0.0", + "eslint-visitor-keys": "^1.2.0", + "espree": "^7.1.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-config-airbnb-base": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz", + "integrity": "sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.9", + "object.assign": "^4.1.0", + "object.entries": "^1.1.2" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.21.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz", + "integrity": "sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.3", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz", + "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==", + "dev": true + }, + "espree": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", + "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", + "dev": true, + "requires": { + "acorn": "^7.2.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.2.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "inquirer": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", + "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "uuid": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", + "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==" + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xml-js": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.8.tgz", + "integrity": "sha512-kUv/geyN80d+s1T68uBfjoz+PjNUjwwf5AWWRwKRqqQaGozpMVsFsKYnenPsxlbN/VL7f0ia8NfLLPCDwX+95Q==", + "requires": { + "sax": "^1.2.4" + } + } + } +} diff --git a/init/onboard-central-ledger/package.json b/init/onboard-central-ledger/package.json new file mode 100644 index 00000000..d8355a86 --- /dev/null +++ b/init/onboard-central-ledger/package.json @@ -0,0 +1,24 @@ +{ + "name": "onboard-central-ledger", + "version": "11.0.3", + "description": "", + "main": "onboard-dfsp.js", + "dependencies": { + "@mojaloop/finance-portal-lib": "0.0.19-snapshot", + "node-fetch": "^2.6.1", + "uuid": "^8.2.0" + }, + "devDependencies": { + "eslint": "^7.2.0", + "eslint-config-airbnb-base": "^14.2.0", + "eslint-plugin-import": "^2.21.2" + }, + "scripts": { + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "start": "node onboard-dfsp.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Kamuela Franco ", + "license": "Apache-2.0" +} diff --git a/init/onboard-hub-accounts/Dockerfile b/init/onboard-hub-accounts/Dockerfile new file mode 100644 index 00000000..aeb3611c --- /dev/null +++ b/init/onboard-hub-accounts/Dockerfile @@ -0,0 +1,28 @@ +FROM node:12.18.2-alpine as builder + +ARG CREATED +ARG SOURCE +ARG REVISION +ARG VERSION + +# See https://github.com/opencontainers/image-spec/blob/master/annotations.md#pre-defined-annotation-keys and https://github.com/opencontainers/image-spec/blob/master/spec.md for info +LABEL org.opencontainers.image.created=${CREATED} +LABEL org.opencontainers.image.url="https://mojaloop.io/" +LABEL org.opencontainers.image.source=${SOURCE} +LABEL org.opencontainers.image.version=${VERSION} +LABEL org.opencontainers.image.revision=${REVISION} +LABEL org.opencontainers.image.title="onboard-central-ledger" +LABEL org.opencontainers.image.authors="matt.kingston@modusbox.com" +LABEL org.opencontainers.image.licenses="Apache-2.0" + +WORKDIR /opt/onboard-central-ledger +COPY package* *.js /opt/onboard-central-ledger/ + +RUN ["npm", "ci", "--production"] + +FROM node:12.18.2-alpine +WORKDIR /opt/onboard-central-ledger + +COPY --from=builder /opt/onboard-central-ledger . + +CMD ["node", "onboard-hub-accounts.js"] diff --git a/init/onboard-hub-accounts/onboard-hub-accounts.js b/init/onboard-hub-accounts/onboard-hub-accounts.js new file mode 100644 index 00000000..6cdd39ef --- /dev/null +++ b/init/onboard-hub-accounts/onboard-hub-accounts.js @@ -0,0 +1,64 @@ +const uuid = require('uuid'); +const { + onboarding: { + createHubAccount, + sendRequest, + }, +} = require('@mojaloop/finance-portal-lib'); + +function log(message) { + const timestamp = (new Date()).toISOString(); + // eslint-disable-next-line no-console + console.log(`[${timestamp}] ${message}`); +} + +console.log('ENV:'); +console.table({ + ACCOUNTS: process.env.ACCOUNTS, + AUTH_BEARER_TOKEN: process.env.AUTH_BEARER_TOKEN, + HOST_CENTRAL_LEDGER: process.env.HOST_CENTRAL_LEDGER, + HUB_OPERATOR_NAME: process.env.HUB_OPERATOR_NAME, +}); + +const accounts = JSON.parse(process.env.ACCOUNTS); +const authToken = process.env.AUTH_BEARER_TOKEN; +const hostCentralLedger = process.env.HOST_CENTRAL_LEDGER; +const fspiopSource = process.env.HUB_OPERATOR_NAME; + +async function onboardHubAccounts() { + try { + log('EXE: INIT: sendRequest->createHubAccounts'); + // Deliberately sequential to be more predictable and make debugging a little easier + await accounts.reduce((promise, acc) => promise.then(async () => { + const response = await sendRequest(createHubAccount({ + authToken, + fspiopSource, + hostCentralLedger, + ...acc + })); + if (response.ok) { + log('EXE: SUCC: sendRequest->createHubAccounts'); + } else { + const error = await response.json(); + // Allow re-registering of the same hub account + if ( + response.status === 400 && + error.errorInformation.errorCode === '3003' && + /already/.test(error.errorInformation.errorDescription) + ) { + log(`EXE: FAIL: sendRequest->createHubAccounts:\n${JSON.stringify(error)}`); + log('EXE: INFO: Allowed failure. Continuing.'); + } else { + throw new Error(`Response not OK/2XX: ${JSON.stringify(error)}`); + } + } + }) , Promise.resolve()); + + } catch ({ message }) { + log(`EXE: FAIL: sendRequest->createHubAccounts:\t${message}`); + process.exitCode = 1; + return; + } +} + +onboardHubAccounts(); diff --git a/init/onboard-hub-accounts/package-lock.json b/init/onboard-hub-accounts/package-lock.json new file mode 100644 index 00000000..c10418a4 --- /dev/null +++ b/init/onboard-hub-accounts/package-lock.json @@ -0,0 +1,1751 @@ +{ + "name": "onboard-hub-accounts", + "version": "11.0.3", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@mojaloop/finance-portal-lib": { + "version": "0.0.20-snapshot", + "resolved": "https://registry.npmjs.org/@mojaloop/finance-portal-lib/-/finance-portal-lib-0.0.20-snapshot.tgz", + "integrity": "sha512-8ZV50K2aSdD+RhU3lZUwVFdDGWJKmeAP11JH7njT4wPzrgVklf9STu1fHx/3dqcnewGso3yEC0oNSER2Edvb6w==", + "requires": { + "abort-controller": "^3.0.0", + "big.js": "5.2.2", + "node-fetch": "2.3.0", + "uuid": "3.3.2", + "xml-js": "1.6.8" + }, + "dependencies": { + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "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, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.2.0.tgz", + "integrity": "sha512-B3BtEyaDKC5MlfDa2Ha8/D6DsS4fju95zs0hjS3HdGazw+LNayai38A25qMppK37wWGWNYSPOR6oYzlz5MHsRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.0.0", + "eslint-visitor-keys": "^1.2.0", + "espree": "^7.1.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-config-airbnb-base": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz", + "integrity": "sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.9", + "object.assign": "^4.1.0", + "object.entries": "^1.1.2" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.21.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz", + "integrity": "sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.3", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz", + "integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==", + "dev": true + }, + "espree": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", + "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", + "dev": true, + "requires": { + "acorn": "^7.2.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.2.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "inquirer": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", + "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "uuid": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", + "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==" + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "xml-js": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.8.tgz", + "integrity": "sha512-kUv/geyN80d+s1T68uBfjoz+PjNUjwwf5AWWRwKRqqQaGozpMVsFsKYnenPsxlbN/VL7f0ia8NfLLPCDwX+95Q==", + "requires": { + "sax": "^1.2.4" + } + } + } +} diff --git a/init/onboard-hub-accounts/package.json b/init/onboard-hub-accounts/package.json new file mode 100644 index 00000000..78860b15 --- /dev/null +++ b/init/onboard-hub-accounts/package.json @@ -0,0 +1,24 @@ +{ + "name": "onboard-hub-accounts", + "version": "11.0.3", + "description": "", + "main": "onboard-hub-accounts.js", + "dependencies": { + "@mojaloop/finance-portal-lib": "0.0.20-snapshot", + "node-fetch": "^2.6.1", + "uuid": "^8.2.0" + }, + "devDependencies": { + "eslint": "^7.2.0", + "eslint-config-airbnb-base": "^14.2.0", + "eslint-plugin-import": "^2.21.2" + }, + "scripts": { + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "start": "node onboard-hub-accounts.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Matt Kingston ", + "license": "Apache-2.0" +} diff --git a/init/onboard-msisdn-oracle/Dockerfile b/init/onboard-msisdn-oracle/Dockerfile new file mode 100644 index 00000000..e29026a6 --- /dev/null +++ b/init/onboard-msisdn-oracle/Dockerfile @@ -0,0 +1,22 @@ +FROM alpine + +ARG CREATED +ARG SOURCE +ARG REVISION +ARG VERSION + +# See https://github.com/opencontainers/image-spec/blob/master/annotations.md#pre-defined-annotation-keys and https://github.com/opencontainers/image-spec/blob/master/spec.md for info +LABEL org.opencontainers.image.created=${CREATED} +LABEL org.opencontainers.image.url="https://mojaloop.io/" +LABEL org.opencontainers.image.source=${SOURCE} +LABEL org.opencontainers.image.version=${VERSION} +LABEL org.opencontainers.image.revision=${REVISION} +LABEL org.opencontainers.image.title="onboard-msisdn-oracle" +LABEL org.opencontainers.image.authors="aaron.reynoza@modusbox.com" +LABEL org.opencontainers.image.licenses="Apache-2.0" + +RUN apk add --no-cache --upgrade bash curl jq + +COPY insert_msisdns.sh /insert_msisdns.sh + +CMD ["sh", "/insert_msisdns.sh"] diff --git a/init/onboard-msisdn-oracle/insert_msisdns.sh b/init/onboard-msisdn-oracle/insert_msisdns.sh new file mode 100755 index 00000000..2daf8a1e --- /dev/null +++ b/init/onboard-msisdn-oracle/insert_msisdns.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env sh + +set -eux + +CURRENT_DATE=$(date) +for participantMSISDN in $(echo "${MSISDN_LIST}" | jq -c '.[]'); do + MSISDN=$(echo "${participantMSISDN}" | jq -r '.MSISDN'); + CURRENCY=$(echo "${participantMSISDN}" | jq -r '.currency'); + DATA="{\"currency\": \"${CURRENCY}\", \"fspId\": \"${DFSP_NAME}\"}" + + curl -v --location --request PUT "${HOST_PATHFINDER_ORACLE}/participants/MSISDN/${MSISDN}" \ + --header 'Content-Type: application/json' \ + --header "date: ${CURRENT_DATE}" \ + --header "fspiop-source: ${DFSP_NAME}" \ + --data-raw "${DATA}"; +done + +echo "MSISDN's have been onboarded" diff --git a/src/audit-resolve.json b/src/audit-resolve.json index 82d269f5..b94cd3e0 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -1,317 +1,41 @@ { "decisions": { - "1300|nyc>istanbul-reports>handlebars": { - "madeAt": 0, - "decision": "fix" - }, - "1316|nyc>istanbul-reports>handlebars": { - "madeAt": 0, - "decision": "fix" - }, - "1324|nyc>istanbul-reports>handlebars": { - "madeAt": 0, - "decision": "fix" - }, - "1325|nyc>istanbul-reports>handlebars": { - "madeAt": 0, - "decision": "fix" - }, - "1500|npm-audit-resolver>yargs-unparser>yargs>yargs-parser": { - "decision": "ignore", - "madeAt": 1602252044897, - "expiresAt": 1604844018565 - }, "1500|npm-audit-resolver>audit-resolve-core>yargs-parser": { "decision": "ignore", - "madeAt": 1602252039657, - "expiresAt": 1604844018565 - }, - "1523|ava>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|eslint>inquirer>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|eslint>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|eslint>table>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|npm-audit-resolver>yargs-unparser>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-optimise-call-expression>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 - }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>lodash": { - "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 + "madeAt": 1594258444388, + "expiresAt": 1594863234907 }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>lodash": { + "1589|sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 + "madeAt": 1607553157718, + "expiresAt": 1610145105148 }, - "1523|nyc>istanbul-lib-instrument>@babel/traverse>lodash": { + "1589|00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 + "madeAt": 1607553157718, + "expiresAt": 1610145105148 }, - "1523|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>lodash": { + "1589|00unidentified>00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 + "madeAt": 1607553157718, + "expiresAt": 1610145105148 }, - "1523|nyc>istanbul-lib-instrument>@babel/core>lodash": { + "1589|ava>update-notifier>latest-version>package-json>registry-auth-token>rc>ini": { "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 + "madeAt": 1607553157718, + "expiresAt": 1610145105148 }, - "1523|tap-xunit>xmlbuilder>lodash": { + "1589|ava>update-notifier>latest-version>package-json>registry-url>rc>ini": { "decision": "ignore", - "madeAt": 1602252048123, - "expiresAt": 1604844018565 + "madeAt": 1607553157718, + "expiresAt": 1610145105148 }, - "1556|node-fetch": { + "1589|ava>update-notifier>is-installed-globally>global-dirs>ini": { "decision": "ignore", - "madeAt": 1602252035571, - "expiresAt": 1604844018565 + "madeAt": 1607553157718, + "expiresAt": 1610145105148 } }, "rules": {}, "version": 1 -} \ No newline at end of file +} diff --git a/src/config.js b/src/config.js index 1e809764..8b501280 100644 --- a/src/config.js +++ b/src/config.js @@ -52,6 +52,12 @@ const config = { key: null, }, }, + ports: { + simulatorApi: 3000, + reportApi: 3002, + testApi: 3003, + }, + parties: [], }; @@ -70,6 +76,10 @@ const setConfig = async (cfg) => { readFile(cfg.SERVER_KEY_PATH), ]); } + config.ports.simulatorApi = cfg.SIMULATOR_API_LISTEN_PORT || config.ports.simulatorApi; + config.ports.reportApi = cfg.REPORT_API_LISTEN_PORT || config.ports.reportApi; + config.ports.testApi = cfg.TEST_API_LISTEN_PORT || config.ports.testApi; + config.parties = cfg.PARTIES ? JSON.parse(cfg.PARTIES) : config.parties; }; diff --git a/src/index.js b/src/index.js index 6d490b77..76958278 100644 --- a/src/index.js +++ b/src/index.js @@ -19,6 +19,9 @@ - Name Surname * Mowali + + * ModusBox + - Steven Oderayi -------------- ******/ 'use strict'; @@ -85,6 +88,7 @@ async function rewriteContentTypeHeader(ctx, next) { (async function start() { // Set up the config from the environment await setConfig(process.env); + const conf = getConfig(); // Set up a logger for each running server const space = Number(process.env.LOG_INDENT); @@ -102,7 +106,7 @@ async function rewriteContentTypeHeader(ctx, next) { // Initialise the model const model = new Model(); - await model.init(process.env.MODEL_DATABASE); + await model.init({ databaseFilepath: process.env.MODEL_DATABASE, parties: conf.parties }); // Log raw to console as a last resort- if the logging framework crashes const failSafe = async (ctx, next) => { @@ -280,10 +284,9 @@ async function rewriteContentTypeHeader(ctx, next) { // If config specifies TLS, start an HTTPS server; otherwise HTTP let simServer; - const conf = getConfig(); - const simulatorPort = 3000; - const reportPort = 3002; - const testApiPort = 3003; + const simulatorPort = conf.ports.simulatorApi; + const reportPort = conf.ports.reportApi; + const testApiPort = conf.ports.testApi; if (conf.tls.mutualTLS.enabled || conf.tls.enabled) { if (!(conf.tls.creds.ca && conf.tls.creds.cert && conf.tls.creds.key)) { diff --git a/src/models/bulkQuote.js b/src/models/bulkQuote.js new file mode 100644 index 00000000..c76c3132 --- /dev/null +++ b/src/models/bulkQuote.js @@ -0,0 +1,123 @@ +/***** + License + -------------- + Copyright © 2020 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 + * ModusBox + - Steven Oderayi + -------------- + ******/ +'use strict'; + +/** + * @file Simulator resources BulkQuote model + * @description Defines the bulk quote model structure and operations within the simulator. + */ +const { bulkQuoteTable } = require('./constants'); + +// eslint-disable-next-line import/no-unresolved +require('dotenv').config(); + +/** + * @typedef {Object} BulkQuote + * + * Data model for bulk quotes. + */ +module.exports = class BulkQuote { + constructor(db) { + this.db = db; + } + + /** + * Gets a BulkQuote with the provided bulkQuoteId + * + * @async + * @param {String} bulkQuoteId The bulk quote Id. + * @returns {Promise} BulkQuote object. + */ + async get(bulkQuoteId) { + const res = await this.db.get(`SELECT * FROM ${bulkQuoteTable} WHERE id = ?`, [bulkQuoteId]); + return res; + } + + /** + * Creates a bulk quote. + * + * @async + * @param {Object} bulkQuoteRequest The bulk quote request object. + * @returns {Promise} The BulkQuote response. + */ + async create(bulkQuoteRequest) { + const { bulkQuoteId } = bulkQuoteRequest; + const individualQuoteResults = bulkQuoteRequest.individualQuotes.map((quote) => { + const fee = Math + .floor(Number(quote.amount) * Number(process.env.FEE_MULTIPLIER)) + .toString(); + return { + quoteId: quote.quoteId, + transactionId: quote.transactionId, + transferAmount: quote.amount, + transferAmountCurrency: quote.currency, + payeeFspFeeAmount: fee, + payeeFspFeeAmountCurrency: quote.currency, + payeeFspCommissionAmount: fee, + payeeFspCommissionAmountCurrency: quote.currency, + }; + }); + const response = { + bulkQuoteId, + individualQuoteResults, + }; + const reqStr = JSON.stringify(bulkQuoteRequest); + const resStr = JSON.stringify(response); + const created = new Date().toISOString().slice(0, 19); + + await this.db.get(`INSERT INTO ${bulkQuoteTable} (id, request, response, created) VALUES (?, ?, ?, ?)`, + [bulkQuoteId, reqStr, resStr, created]); + + return response; + } + + /** + * Updates a bulk quote + * + * @param {String} currentBulkOuoteId The bulk quote id to update. + * @param {Object} newBulkQuoteRequest The new BulkQuote object. + */ + async update(currentBulkOuoteId, newBulkQuoteRequest) { + const response = newBulkQuoteRequest.individualQuotes.map( + (quote) => ({ transferAmount: quote.amount, transferAmountCurrency: quote.currency }), + ); + const reqStr = JSON.stringify(newBulkQuoteRequest); + const resStr = JSON.stringify(response); + + await this.db.run(` + UPDATE ${bulkQuoteTable} + SET id = ?, request = ?, response = ? + WHERE id = ?`, [newBulkQuoteRequest.bulkQuoteId, reqStr, resStr, currentBulkOuoteId]); + } + + /** + * Deletes a BulkQuote. + * + * @async + * @param {String} bulkQuoteId The bulk quote id. + */ + async delete(bulkQuoteId) { + await this.db.run(`DELETE FROM ${bulkQuoteTable} WHERE id = ?`, [bulkQuoteId]); + } +}; diff --git a/src/models/bulkTransfer.js b/src/models/bulkTransfer.js new file mode 100644 index 00000000..7e3e64d5 --- /dev/null +++ b/src/models/bulkTransfer.js @@ -0,0 +1,103 @@ +/***** + License + -------------- + Copyright © 2020 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 + * ModusBox + - Steven Oderayi + -------------- + ******/ +'use strict'; + +/** + * @file Simulator resources BulkTransfer model + * @description Defines the bulk transfer model structure and operations within the simulator. + */ +const { bulkTransferTable } = require('./constants'); +require('dotenv').config(); + +/** + * @typedef {Object} BulkTransfer + * + * Data model for bulk transfer. + */ +module.exports = class BulkTransfer { + constructor(db) { + this.db = db; + } + + /** + * Retrieves a bulk transfer + * + * @async + * @param {String} bulkTransferId The bulk transfer id. + * @returns {Promise} BulkTransfer object. + */ + async get(bulkTransferId) { + const res = await this.db.get(`SELECT * FROM ${bulkTransferTable} WHERE id = ?`, [bulkTransferId]); + return res; + } + + /** + * Creates a bulk transfer. + * + * @async + * @param {Object} bulkTransferRequest The bulk transfer request object. + * @returns {Promise} BulkTransfer response. + */ + async create(bulkTransferRequest) { + const { bulkTransferId } = bulkTransferRequest; + const response = { bulkTransferId }; + response.individualTransferResults = bulkTransferRequest.individualTransfers.map( + (transfer) => ({ transferId: transfer.transferId }), + ); + const reqStr = JSON.stringify(bulkTransferRequest); + const resStr = JSON.stringify(response); + + await this.db.get(`INSERT INTO ${bulkTransferTable} (id, request, response) VALUES (?, ?, ?)`, [bulkTransferId, reqStr, resStr]); + + return response; + } + + /** + * Updates a bulk transfer + * + * @param {String} bulkTransferId The current bulk transfer id. + * @param {Object} BulkTansferRequest The new BulkTransfer object. + */ + async update(currentBulkTransferId, bulkTransferRequest) { + const { homeTransactionId: newBulkTransferId } = bulkTransferRequest; + const response = { newBulkTransferId }; + const reqStr = JSON.stringify(bulkTransferRequest); + const resStr = JSON.stringify(response); + + await this.db.run(` + UPDATE ${bulkTransferTable} + SET id = ?, request = ?, response = ? + WHERE id = ?`, [newBulkTransferId, reqStr, resStr, currentBulkTransferId]); + } + + /** + * Deletes a bulk transfer. + * + * @async + * @param {String} bulkTransferId The bulk transfer id. + */ + async delete(bulkTransferId) { + await this.db.run(`DELETE FROM ${bulkTransferTable} WHERE id = ?`, [bulkTransferId]); + } +}; diff --git a/src/models/constants.js b/src/models/constants.js index 45bb3a1a..657786b9 100644 --- a/src/models/constants.js +++ b/src/models/constants.js @@ -27,6 +27,8 @@ const partyTable = 'party'; const quoteTable = 'quote'; const transactionRequestTable = 'transactionRequest'; const transferTable = 'transfer'; +const bulkQuoteTable = 'bulkQuote'; +const bulkTransferTable = 'bulkTransfer'; const partyExtensionTable = 'partyExtension'; const createPartyTable = ` @@ -37,19 +39,40 @@ CREATE TABLE IF NOT EXISTS ${partyTable} ( lastName TEXT, dateOfBirth TEXT, idType TEXT, - idValue TEXT NOT NULL PRIMARY KEY, + idValue TEXT NOT NULL, + subIdValue TEXT, CHECK(idValue <> '') ) `; + +// below index is a workaround to avoid the duplicates since sqlite treats every null as a unique value +// thus allowing to insert multiple records for same the idValue having subIdValue as NULL +const createPartyTableUniqueIndex = ` +CREATE UNIQUE INDEX IF NOT EXISTS idx_party_unique ON ${partyTable} ( + idValue, + IFNULL(subIdValue, '') +) +`; + const createPartyExtensionTable = ` CREATE TABLE IF NOT EXISTS ${partyExtensionTable} ( idValue TEXT NOT NULL, + subIdValue TEXT, key TEXT NOT NULL, - value TEXT NOT NULL, - PRIMARY KEY (idValue, key), - FOREIGN KEY (idValue) REFERENCES party(idValue) ON DELETE CASCADE + value TEXT NOT NULL +) +`; + +// below index is a workaround to avoid the duplicates since sqlite treats every null as a unique value +// thus allowing to insert multiple records for same the idValue/key having subIdValue as NULL +const createPartyExtensionTableUniqueIndex = ` +CREATE UNIQUE INDEX IF NOT EXISTS idx_party_extension_unique ON ${partyExtensionTable} ( + idValue, + IFNULL(subIdValue, ''), + key ) `; + const createQuoteTable = ` CREATE TABLE IF NOT EXISTS ${quoteTable} ( id TEXT NOT NULL PRIMARY KEY, @@ -60,6 +83,16 @@ CREATE TABLE IF NOT EXISTS ${quoteTable} ( ) `; +const createBulkQuoteTable = ` +CREATE TABLE IF NOT EXISTS ${bulkQuoteTable} ( + id TEXT NOT NULL PRIMARY KEY, + request TEXT, + response TEXT, + created TIMESTAMP + CHECK(id <> '') +) +`; + const createTransactionRequestTable = ` CREATE TABLE IF NOT EXISTS ${transactionRequestTable} ( id TEXT NOT NULL PRIMARY KEY, @@ -79,27 +112,41 @@ CREATE TABLE IF NOT EXISTS ${transferTable} ( ) `; +const createBulkTransferTable = ` +CREATE TABLE IF NOT EXISTS ${bulkTransferTable} ( + id TEXT NOT NULL PRIMARY KEY, + request TEXT, + response TEXT, + CHECK(id <> '') +) +`; + const createAccountTable = ` CREATE TABLE IF NOT EXISTS ${partyAccountsTable} ( address TEXT NOT NULL PRIMARY KEY, currency TEXT NOT NULL, description TEXT NOT NULL, - idValue TEXT NOT NULL, - FOREIGN KEY (idValue) REFERENCES party(idValue) ON DELETE CASCADE + idValue TEXT NOT NULL ) `; module.exports = { partyTable, quoteTable, + bulkQuoteTable, + transferTable, + bulkTransferTable, transactionRequestTable, + partyExtensionTable, createPartyTable, createQuoteTable, + createBulkQuoteTable, + createBulkTransferTable, createTransactionRequestTable, createTransferTable, - transferTable, - partyExtensionTable, createPartyExtensionTable, + createPartyTableUniqueIndex, + createPartyExtensionTableUniqueIndex, partyAccountsTable, createAccountTable, }; diff --git a/src/models/model.js b/src/models/model.js index 5c659e59..445d20f1 100644 --- a/src/models/model.js +++ b/src/models/model.js @@ -31,15 +31,21 @@ const sqlite = require('sqlite'); const Party = require('./party'); const Quote = require('./quote'); +const BulkQuote = require('./bulkQuote'); const TransactionRequest = require('./transactionrequest'); const Transfer = require('./transfer'); +const BulkTransfer = require('./bulkTransfer'); const { createPartyTable, - createTransferTable, + createPartyTableUniqueIndex, createQuoteTable, + createBulkQuoteTable, + createTransferTable, + createBulkTransferTable, createTransactionRequestTable, createPartyExtensionTable, + createPartyExtensionTableUniqueIndex, createAccountTable, } = require('./constants'); @@ -55,8 +61,10 @@ module.exports = class Model { this.db = null; this.party = null; this.quote = null; + this.bulkQuote = null; this.transactionrequest = null; this.transfer = null; + this.bulkTransfer = null; } /** @@ -74,30 +82,37 @@ module.exports = class Model { * Initialises db. * * @async - * @param {String} databaseFilepath SqliteDB file path + * @param {String} databaseFilepath SqliteDB file path + * @param [{Object}] parties Array of party objects to create after db initialisation * @throws {Error} */ - async init(databaseFilepath) { + async init({ databaseFilepath, parties }) { if (this.db) { throw new Error('Attempted to initialise database twice'); } - try { - this.db = await sqlite.open(databaseFilepath); - await this.db.run('PRAGMA foreign_keys = true'); - await this.db.run(createPartyTable); - await this.db.run(createQuoteTable); - await this.db.run(createTransactionRequestTable); - await this.db.run(createTransferTable); - await this.db.run(createPartyExtensionTable); - await this.db.run(createAccountTable); + this.db = await sqlite.open(databaseFilepath); + await this.db.run('PRAGMA foreign_keys = true'); + await this.db.run(createPartyTable); + await this.db.run(createPartyTableUniqueIndex); + await this.db.run(createQuoteTable); + await this.db.run(createTransactionRequestTable); + await this.db.run(createTransferTable); + await this.db.run(createPartyExtensionTable); + await this.db.run(createPartyExtensionTableUniqueIndex); + await this.db.run(createBulkQuoteTable); + await this.db.run(createBulkTransferTable); + await this.db.run(createAccountTable); + + this.party = new Party(this.db); + this.quote = new Quote(this.db); + this.bulkQuote = new BulkQuote(this.db); + this.transactionrequest = new TransactionRequest(this.db); + this.transfer = new Transfer(this.db); + this.bulkTransfer = new BulkTransfer(this.db); - this.party = new Party(this.db); - this.quote = new Quote(this.db); - this.transactionrequest = new TransactionRequest(this.db); - this.transfer = new Transfer(this.db); - } catch (err) { - throw new Error(err); + if (parties) { + await Promise.all(parties.map((p) => this.party.create(p))); } } }; diff --git a/src/models/party.js b/src/models/party.js index 737f083b..56faa934 100644 --- a/src/models/party.js +++ b/src/models/party.js @@ -47,16 +47,27 @@ module.exports = class Party { * @async * @param {String} idType The party idType. * @param {String} idValue The party idValue. + * @param {String} subIdValue The optional party subIdValue. * @returns {Promise} Party object. */ - async get(idType, idValue) { - const res = await this.db.all(` - SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, pe.key, pe.value, pa.address, pa.currency, pa.description - FROM ${partyTable} p - LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue - LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue - WHERE p.idType = ? AND p.idValue = ?`, [idType, idValue]); + async get(idType, idValue, subIdValue = null) { + let res; + if (!subIdValue) { + res = await this.db.all(` + SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value, pa.address, pa.currency, pa.description + FROM ${partyTable} p + LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue + LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue + WHERE p.idType = ? AND p.idValue = ? AND p.subIdValue IS NULL AND pe.subIdValue IS NULL`, [idType, idValue]); + } else { + res = await this.db.all(` + SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value, pa.address, pa.currency, pa.description + FROM ${partyTable} p + LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue AND p.subIdValue = pe.subIdValue + LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue + WHERE p.idType = ? AND p.idValue = ? AND p.subIdValue = ?`, [idType, idValue, subIdValue]); + } const resultMap = {}; res.forEach((row) => { let party; @@ -72,6 +83,9 @@ module.exports = class Party { idType: row.idType, idValue: row.idValue, }; + if (row.subIdValue) { + party.subIdValue = row.subIdValue; + } resultMap[row.idValue] = party; } if (row.key) { @@ -105,15 +119,15 @@ module.exports = class Party { */ async getAll() { const res = await this.db.all(` - SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, pe.key, pe.value, pa.address, pa.currency, pa.description - FROM ${partyTable} p - LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue - LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue`); + SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value, pa.address, pa.currency, pa.description + FROM ${partyTable} p + LEFT JOIN ${partyExtensionTable} pe ON (p.idValue = pe.idValue AND pe.subIdValue IS NULL AND p.subIdValue IS NULL) OR (p.idValue = pe.idValue AND p.subIdValue = pe.subIdValue) + LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue`); const resultMap = {}; res.forEach((row) => { let party; - if (resultMap[row.idValue]) { - party = resultMap[row.idValue]; + if (resultMap[`${row.idValue}-${row.subIdValue}`]) { + party = resultMap[`${row.idValue}-${row.subIdValue}`]; } else { party = { displayName: row.displayName, @@ -124,7 +138,10 @@ module.exports = class Party { idType: row.idType, idValue: row.idValue, }; - resultMap[row.idValue] = party; + if (row.subIdValue) { + party.subIdValue = row.subIdValue; + } + resultMap[`${row.idValue}-${row.subIdValue}`] = party; } if (row.key) { if (!party.extensionList) { @@ -155,19 +172,17 @@ module.exports = class Party { */ async create(party) { const { - displayName, firstName, middleName, lastName, dateOfBirth, idType, idValue, + displayName, firstName, middleName, lastName, dateOfBirth, idType, idValue, subIdValue, } = party; - await this.db.get(` - INSERT INTO ${partyTable} (displayName, firstName, middleName, lastName, dateOfBirth, idType, idValue) - VALUES (?, ?, ?, ?, ?, ?, ?)`, - [displayName, firstName, middleName, lastName, dateOfBirth, idType, idValue]); + await this.db.get(`INSERT INTO ${partyTable} (displayName, firstName, middleName, lastName, dateOfBirth, idType, idValue, subIdValue) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, + [displayName, firstName, middleName, lastName, dateOfBirth, idType, idValue, subIdValue]); if (party.extensionList) { const { extensionList } = party; extensionList.forEach((extension) => { - this.db.get(` - INSERT INTO ${partyExtensionTable} (idValue, key, value) - VALUES (?, ?, ?)`, - [idValue, extension.key, extension.value]); + this.db.get(`INSERT INTO ${partyExtensionTable} (idValue, subIdValue, key, value) + VALUES (?, ?, ?, ?)`, + [idValue, subIdValue, extension.key, extension.value]); }); } if (party.accounts) { @@ -183,46 +198,77 @@ module.exports = class Party { /** * Updates a party * - * @param {String} idValue The party idValue to update. * @param {Object} newParty The new Party object. + * @param {String} idType The party idType to update. + * @param {String} idValue The party idValue to update. + * @param {String} subIdValue The optional party subIdValue to update. */ - async update(idType, idValue, newParty) { + async update(newParty, idType, idValue, subIdValue = null) { const { displayName, firstName, middleName, lastName, dateOfBirth, } = newParty; - await this.db.run(` - UPDATE ${partyTable} - SET displayName = ?, firstName = ?, middleName = ?, lastName = ?, dateOfBirth = ?, idType = ?, idValue = ? - WHERE idType = ? AND idValue = ?`, - [displayName, - firstName, - middleName, - lastName, - dateOfBirth, - idType, - idValue, - idType, - idValue]); - if (newParty.extensionList) { - const { extensionList } = newParty; - extensionList.forEach((extension) => { - this.db.run(` - UPDATE ${partyExtensionTable} - SET value = ? - WHERE key = ?`, - [extension.value, extension.key]); - this.db.run(` - INSERT OR IGNORE INTO ${partyExtensionTable} (idValue, key, value) - VALUES (?, ?, ?)`, - [idValue, extension.key, extension.value]); - }); - } - if (newParty.accounts) { - const { accounts } = newParty; - await Promise.all(accounts.map(async (account) => this.db.run(` - INSERT OR IGNORE INTO ${partyAccountsTable} (idValue, address, currency, description) - VALUES (?, ?, ?, ?);`, - [idValue, account.address, account.currency, account.description]))); + if (!subIdValue) { + // If subIdValue is not passed then only updated the record where subIdValue IS NULL + // This will make sure we accidentally don't update all records for idValue by ignoring subIdValue + await this.db.run(` + UPDATE ${partyTable} + SET displayName = ?, firstName = ?, middleName = ?, lastName = ?, dateOfBirth = ?, idType = ?, idValue = ? + WHERE idType = ? AND idValue = ? AND subIdValue IS NULL`, + [displayName, + firstName, + middleName, + lastName, + dateOfBirth, + idType, + idValue, + idType, + idValue]); + + if (newParty.extensionList) { + const { extensionList } = newParty; + extensionList.forEach((extension) => { + this.db.run(` + UPDATE ${partyExtensionTable} + SET value = ? + WHERE key = ? AND idValue = ? AND subIdValue IS NULL`, + [extension.value, extension.key, idValue]); + this.db.run(` + INSERT OR IGNORE INTO ${partyExtensionTable} (idValue, subIdValue, key, value) + VALUES (?, ?, ?, ?)`, + [idValue, subIdValue, extension.key, extension.value]); + }); + } + } else { + // Update the record for a specific idValue and subIdValue + await this.db.run(` + UPDATE ${partyTable} + SET displayName = ?, firstName = ?, middleName = ?, lastName = ?, dateOfBirth = ?, idType = ?, idValue = ?, subIdValue = ? + WHERE idType = ? AND idValue = ? AND subIdValue = ?`, + [displayName, + firstName, + middleName, + lastName, + dateOfBirth, + idType, + idValue, + subIdValue, + idType, + idValue, + subIdValue]); + if (newParty.extensionList) { + const { extensionList } = newParty; + extensionList.forEach((extension) => { + this.db.run(` + UPDATE ${partyExtensionTable} + SET value = ? + WHERE key = ? AND idValue = ? AND subIdValue = ?`, + [extension.value, extension.key, idValue, subIdValue]); + this.db.run(` + INSERT OR IGNORE INTO ${partyExtensionTable} (idValue, subIdValue, key, value) + VALUES (?, ?, ?, ?)`, + [idValue, subIdValue, extension.key, extension.value]); + }); + } } } @@ -231,8 +277,15 @@ module.exports = class Party { * * @param {String} idType The party idType. * @param {String} idValue The party idValue. + * @param {String} subIdValue The optional party subIdValue. */ - async delete(idType, idValue) { - await this.db.run(`DELETE FROM ${partyTable} WHERE idType = ? AND idValue = ?`, [idType, idValue]); + async delete(idType, idValue, subIdValue = null) { + if (!subIdValue) { + await this.db.run(`DELETE FROM ${partyTable} WHERE idType = ? AND idValue = ? AND subIdValue IS NULL`, [idType, idValue]); + await this.db.run(`DELETE FROM ${partyExtensionTable} WHERE idValue = ? AND subIdValue IS NULL`, [idValue]); + } else { + await this.db.run(`DELETE FROM ${partyTable} WHERE idType = ? AND idValue = ? AND subIdValue = ?`, [idType, idValue, subIdValue]); + await this.db.run(`DELETE FROM ${partyExtensionTable} WHERE idValue = ? AND subIdValue = ?`, [idValue, subIdValue]); + } } }; diff --git a/src/models/transfer.js b/src/models/transfer.js index cfe8c118..cf3266d2 100644 --- a/src/models/transfer.js +++ b/src/models/transfer.js @@ -75,16 +75,13 @@ module.exports = class Transfer { * @param {String} transferId The current transfer id. * @param {Object} TansferRequest The new transfer object. */ - async update(currentTransferId, transferRequest) { - const { homeTransactionId: newTransferId } = transferRequest; - const response = { newTransferId }; - const reqStr = JSON.stringify(transferRequest); - const resStr = JSON.stringify(response); + async update(currentTransferId, transferResponse) { + const resStr = JSON.stringify(transferResponse); await this.db.run(` UPDATE ${transferTable} - SET id = ?, request = ?, response = ? - WHERE id = ?`, [newTransferId, reqStr, resStr, currentTransferId]); + SET response = ? + WHERE id = ?`, [resStr, currentTransferId]); } /** diff --git a/src/package-lock.json b/src/package-lock.json index fbc978a6..f74dde54 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -1,6 +1,6 @@ { "name": "mojaloop-simulator", - "version": "9.4.1", + "version": "11.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -383,29 +383,6 @@ "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "json-schema-ref-parser": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-6.0.3.tgz", - "integrity": "sha512-Ds/0541IPed88JSiMb3CBeUsxfL5Eosc0r97z0QMSXiBJTYKZLhOAGZd8zFVfpkKaRb4zDAnumyFYxnHLmbQmw==", - "requires": { - "call-me-maybe": "^1.0.1", - "js-yaml": "^3.12.1", - "ono": "^4.0.11" - } - }, - "openapi-jsonschema-parameters": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/openapi-jsonschema-parameters/-/openapi-jsonschema-parameters-1.1.0.tgz", - "integrity": "sha512-TCDHFK3oL842ne50EIymIXgvVbbMjohjjaieGDGW0hzbz3vJE9u3OjORB+p0IaKg5TbOsrpF8SNg3OvjcehBUg==", - "requires": { - "openapi-types": "^1.3.1" - } } } }, @@ -582,6 +559,13 @@ "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "dependencies": { + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + } } }, "ansi-align": { @@ -762,49 +746,25 @@ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, "audit-resolve-core": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/audit-resolve-core/-/audit-resolve-core-1.1.7.tgz", - "integrity": "sha512-9nLm9SgyMbMv86X5a/E6spcu3V+suceHF6Pg4BwjPqfxWBKDvISagJH9Ji592KihqBev4guKFO3BiNEVNnqh3A==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/audit-resolve-core/-/audit-resolve-core-1.1.8.tgz", + "integrity": "sha512-F3IWaxu1Xw4OokmtG9hkmsKoJt8DQS7RZvot52zXHsANKvzFRMKVNTP1DAz1ztlRGmJx1XV16PcE+6m35bYoTA==", "dev": true, "requires": { "concat-stream": "^1.6.2", "debug": "^4.1.1", "djv": "^2.1.2", "spawn-shell": "^2.1.0", - "yargs-parser": "^10.1.0" + "yargs-parser": "^18.1.3" }, "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -815,12 +775,13 @@ } }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -911,29 +872,11 @@ } } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, "binary-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", @@ -1106,11 +1049,6 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -1358,14 +1296,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, "common-path-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", @@ -1574,14 +1504,6 @@ "fast-bind": "^1.0.0" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, "date-time": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/date-time/-/date-time-2.1.0.tgz", @@ -1592,9 +1514,9 @@ } }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { "ms": "^2.1.1" } @@ -1728,11 +1650,6 @@ } } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -1811,15 +1728,6 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2313,9 +2221,9 @@ "dev": true }, "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==" }, "events-to-array": { "version": "1.1.2", @@ -2323,26 +2231,6 @@ "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", "dev": true }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, "external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", @@ -2354,20 +2242,15 @@ "tmp": "^0.0.33" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, "fast-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fast-bind/-/fast-bind-1.0.0.tgz", "integrity": "sha1-f6llLLMyX1zR4lLWy08WDeGnbnU=" }, "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-diff": { "version": "1.2.0", @@ -2556,21 +2439,6 @@ } } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, "format-util": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.5.tgz", @@ -2660,14 +2528,6 @@ "pump": "^3.0.0" } }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -2755,20 +2615,6 @@ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2849,6 +2695,20 @@ "requires": { "deep-equal": "~1.0.1", "http-errors": "~1.7.2" + }, + "dependencies": { + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + } } }, "http-cache-semantics": { @@ -2858,25 +2718,22 @@ "dev": true }, "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz", + "integrity": "sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==", "requires": { "depd": "~1.1.2", "inherits": "2.0.4", - "setprototypeof": "1.1.1", + "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + }, + "dependencies": { + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + } } }, "husky": { @@ -3050,12 +2907,6 @@ } } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, "irregular-plurals": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", @@ -3125,9 +2976,9 @@ } }, "is-generator-function": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", - "integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", + "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" }, "is-glob": { "version": "4.0.1", @@ -3214,12 +3065,6 @@ "has": "^1.0.3" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, "is-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", @@ -3238,7 +3083,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-windows": { "version": "1.0.2", @@ -3277,11 +3123,6 @@ "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -3461,11 +3302,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -3496,10 +3332,15 @@ "selectn": "^1.1.2" } }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "json-schema-ref-parser": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-6.0.3.tgz", + "integrity": "sha512-Ds/0541IPed88JSiMb3CBeUsxfL5Eosc0r97z0QMSXiBJTYKZLhOAGZd8zFVfpkKaRb4zDAnumyFYxnHLmbQmw==", + "requires": { + "call-me-maybe": "^1.0.1", + "js-yaml": "^3.12.1", + "ono": "^4.0.11" + } }, "json-schema-traverse": { "version": "0.4.1", @@ -3512,11 +3353,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, "json5": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", @@ -3532,17 +3368,6 @@ "integrity": "sha1-T80kbcXQ44aRkHxEqwAveC0dlMw=", "dev": true }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "keygrip": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", @@ -3649,15 +3474,6 @@ "package-json": "^6.3.0" } }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -3697,9 +3513,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "lodash.clonedeep": { @@ -3815,15 +3631,6 @@ } } }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, "matcher": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz", @@ -3861,17 +3668,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, "merge-options": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz", @@ -3898,16 +3694,16 @@ } }, "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "requires": { - "mime-db": "1.43.0" + "mime-db": "1.44.0" } }, "mimic-fn": { @@ -3977,9 +3773,9 @@ "dev": true }, "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" }, "natural-compare": { "version": "1.4.0", @@ -3988,9 +3784,9 @@ "dev": true }, "needle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.3.tgz", - "integrity": "sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", + "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -4009,9 +3805,9 @@ "dev": true }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-pre-gyp": { "version": "0.11.0", @@ -4245,11 +4041,6 @@ } } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4346,6 +4137,14 @@ "format-util": "^1.0.3" } }, + "openapi-jsonschema-parameters": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/openapi-jsonschema-parameters/-/openapi-jsonschema-parameters-1.1.0.tgz", + "integrity": "sha512-TCDHFK3oL842ne50EIymIXgvVbbMjohjjaieGDGW0hzbz3vJE9u3OjORB+p0IaKg5TbOsrpF8SNg3OvjcehBUg==", + "requires": { + "openapi-types": "^1.3.1" + } + }, "openapi-types": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-1.3.5.tgz", @@ -4409,17 +4208,6 @@ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -4440,24 +4228,6 @@ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, "p-limit": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", @@ -4582,11 +4352,6 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", @@ -4713,11 +4478,6 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -4743,9 +4503,9 @@ } }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" }, "raw-body": { "version": "2.4.1", @@ -4756,6 +4516,20 @@ "http-errors": "1.7.3", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "dependencies": { + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + } } }, "rc": { @@ -4980,33 +4754,6 @@ "es6-error": "^4.0.1" } }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5350,29 +5097,12 @@ } }, "sqlite3": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.1.1.tgz", - "integrity": "sha512-CvT5XY+MWnn0HkbwVKJAyWEMfzpAPwnTiB3TobA5Mri44SrTovmmh499NPQP+gatkeOipqPlBLel7rn4E/PCQg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.2.0.tgz", + "integrity": "sha512-roEOz41hxui2Q7uYnWsjMOTry6TcNUNmp8audCx18gF10P2NknwdpF+E+HKvz/F2NvPKGGBF4NGc+ZPQ+AABwg==", "requires": { "nan": "^2.12.1", - "node-pre-gyp": "^0.11.0", - "request": "^2.87.0" - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + "node-pre-gyp": "^0.11.0" } }, "stack-utils": { @@ -5449,12 +5179,6 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -5738,15 +5462,6 @@ "hoek": "6.x.x" } }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, "trim-off-newlines": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", @@ -5764,19 +5479,6 @@ "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==" }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -5852,9 +5554,9 @@ } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "requires": { "punycode": "^2.1.0" } @@ -5876,7 +5578,8 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true }, "v8-compile-cache": { "version": "2.1.0", @@ -5899,16 +5602,6 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -6187,33 +5880,63 @@ } }, "yargs-unparser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", - "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, "requires": { "flat": "^4.1.0", - "lodash": "^4.17.11", - "yargs": "^12.0.5" + "lodash": "^4.17.15", + "yargs": "^13.3.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "color-name": "1.1.3" } }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -6223,12 +5946,6 @@ "locate-path": "^3.0.0" } }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -6260,102 +5977,59 @@ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { + "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "strip-ansi": "^5.1.0" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" } }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/src/package.json b/src/package.json index aa259586..dc0d5b85 100644 --- a/src/package.json +++ b/src/package.json @@ -1,12 +1,16 @@ { "name": "mojaloop-simulator", - "version": "9.4.1", + "version": "11.3.0", "description": "A canonical test example implementation of the parties, transfers and quotes resources of the Mojaloop API", "license": "Apache-2.0", "main": "index.js", "author": "Matt Kingston, ModusBox Inc.", "contributors": [ + "Aaron Reynoza ", + "Kamuela Franco ", "Matt Kingston ", + "Steven Oderayi ", + "Valentin Genev ", "ModusBox", "Mowali" ], @@ -48,7 +52,7 @@ "koa": "2.11.0", "koa-body": "4.1.1", "mustache": "4.0.0", - "node-fetch": "2.6.0", + "node-fetch": "2.6.1", "sqlite": "3.0.3", "yamljs": "0.3.0" }, diff --git a/src/sim-backend.env b/src/sim-backend.env index e8b2074d..c2aa3c04 100644 --- a/src/sim-backend.env +++ b/src/sim-backend.env @@ -42,3 +42,8 @@ FEE_MULTIPLIER=0.05 # e.g. a rule can be used to trigger NDC errors given transfers between certain limits. RULES_FILE=./rules.json + +# Ports for simulator, report, and test APIs +SIMULATOR_API_LISTEN_PORT=3000 +REPORT_API_LISTEN_PORT=3002 +TEST_API_LISTEN_PORT=3003 diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 716ca5a0..6908aaf3 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -52,6 +52,49 @@ paths: schema: $ref: '#/components/schemas/errorResponse' + /participants/{idType}/{idValue}/{subIdValue}: + get: + summary: Asks for the FSPID of the scheme participant that can handle transfers for the specified identifier type, value and subId value + tags: + - Participants + parameters: + - name: idType + in: path + required: true + schema: + $ref: '#/components/schemas/idType' + - name: idValue + in: path + required: true + schema: + $ref: '#/components/schemas/idValue' + - name: subIdValue + in: path + required: true + schema: + $ref: '#/components/schemas/subIdValue' + responses: + 200: + description: Response containing details of the requested party + content: + application/json: + schema: + $ref: '#/components/schemas/participantsResponse' + 404: + description: The party specified by the provided identifier type and value/subId is not known to the server + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + /parties/{idType}/{idValue}: get: summary: Requests information relating to a transfer party identified by the specified identifier type and value @@ -90,6 +133,49 @@ paths: schema: $ref: '#/components/schemas/errorResponse' + /parties/{idType}/{idValue}/{subIdValue}: + get: + summary: Requests information relating to a transfer party identified by the specified identifier type, value and subId value + tags: + - Parties + parameters: + - name: idType + in: path + required: true + schema: + $ref: '#/components/schemas/idType' + - name: idValue + in: path + required: true + schema: + $ref: '#/components/schemas/idValue' + - name: subIdValue + in: path + required: true + schema: + $ref: '#/components/schemas/subIdValue' + responses: + 200: + description: Response containing details of the requested party + content: + application/json: + schema: + $ref: '#/components/schemas/transferParty' + 404: + description: The party specified by the provided identifier type and value is not known to the server + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + /quoterequests: post: summary: Requests a quote for the specified transfer @@ -183,6 +269,31 @@ paths: schema: $ref: '#/components/schemas/errorResponse' + /transfers/{transferId}: + put: + summary: Receive notification for a specific transfer + description: The HTTP request `PUT /transfers/{transferId}` is used to receive notification for transfer being fulfiled when the FSP is a Payee + tags: + - Transfers + parameters: + - $ref: '#/components/schemas/transferId' + requestBody: + description: An incoming notification for fulfiled transfer + content: + application/json: + schema: + $ref: '#/components/schemas/fulfilNotification' + responses: + 200: + description: The notification was accepted + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + + /otp/{requestToPayId}: get: summary: Requests OTP @@ -215,6 +326,135 @@ paths: application/json: schema: $ref: '#/components/schemas/errorResponse' + + /bulkQuotes: + post: + summary: Requests a bulk quote + tags: + - BulkQuotes + requestBody: + description: Incoming request for a bulk quotation + content: + application/json: + schema: + $ref: '#/components/schemas/bulkQuoteRequest' + responses: + 200: + description: A response to the bulk quote request + content: + application/json: + schema: + $ref: '#/components/schemas/bulkQuoteResponse' + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + + /bulkQuotes/{idValue}: + get: + summary: Requests information relating to a bulk quote identified by the specified identifier value + tags: + - BulkQuotes + parameters: + - name: idValue + in: path + required: true + schema: + $ref: '#/components/schemas/idValue' + responses: + 200: + description: Response containing details of the requested bulk quote + content: + application/json: + schema: + $ref: '#/components/schemas/bulkQuoteResponse' + 404: + description: The bulk quote specified by the provided identifier value is not known to the server + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + + /bulkTransfers: + post: + summary: Execute bulk transfer of funds from an external account to internal accounts + tags: + - BulkTransfers + requestBody: + description: An incoming bulk transfer request + content: + application/json: + schema: + $ref: '#/components/schemas/bulkTransferRequest' + responses: + 200: + description: The bulk transfer was accepted + content: + application/json: + schema: + $ref: '#/components/schemas/bulkTransferResponse' + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + + /bulkTransfers/{idValue}: + get: + summary: Requests information relating to a bulk transfer identified by the specified identifier value + tags: + - BulkTransfers + parameters: + - name: idValue + in: path + required: true + schema: + $ref: '#/components/schemas/idValue' + responses: + 200: + description: Response containing details of the requested bulk transfer + content: + application/json: + schema: + $ref: '#/components/schemas/bulkTransferResponse' + 404: + description: The bulk transfer specified by the provided identifier value is not known to the server + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + /signchallenge: post: @@ -1062,6 +1302,11 @@ components: minLength: 1 maxLength: 128 + subIdValue: + type: string + minLength: 1 + maxLength: 128 + money: pattern: ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$ type: string @@ -1113,6 +1358,9 @@ components: idValue: type: string description: The identifier string used to identify the sender + subIdValue: + type: string + description: The sub identifier string used to identify the sender displayName: type: string description: Display name of the sender if known @@ -1130,6 +1378,225 @@ components: merchantClassificationCode: type: string description: Up to 4 digits specifying the senders merchant classification, if known and applicable + + bulkQuoteRequest: + type: object + description: A request for a bulk quote + required: + - bulkQuoteId + - from + - individualQuotes + properties: + bulkQuoteId: + $ref: '#/components/schemas/bulkQuoteId' + from: + $ref: '#/components/schemas/transferParty' + description: Information about the Payer in the proposed financial transaction. + geoCode: + $ref: '#/components/schemas/geoCode' + description: Longitude and Latitude of the initiating Party. Can be used to detect fraud. + expiration: + $ref: '#/components/schemas/timestamp' + description: An optional deadline for responding to the quote request + individualQuotes: + type: array + minItems: 1 + maxItems: 1000 + items: + $ref: '#/components/schemas/IndividualQuote' + + bulkQuoteResponse: + type: object + description: A response to a request for a bulk quote + required: + - bulkQuoteId + - individualQuoteResults + properties: + bulkQuoteId: + $ref: '#/components/schemas/bulkQuoteId' + description: Id of the bulk quote this response relates to + expiration: + $ref: '#/components/schemas/timestamp' + description: Timestamp specifying the validity period of the bulk quotation + individualQuoteResults: + type: array + minItems: 1 + maxItems: 1000 + items: + $ref: '#/components/schemas/IndividualQuoteResult' + description: Fees for each individual transaction, if any of them are charged per + transaction. + + IndividualQuote: + type: object + description: Data model for individual quote in a bulk quote request + required: + - quoteId + - transactionId + - to + - amountType + - amount + - currency + - transactionType + - initiator + - initiatorType + properties: + quoteId: + $ref: '#/components/schemas/quoteId' + transactionId: + $ref: '#/components/schemas/transactionId' + description: Identifier for the transaction, decided by the Payer FSP during the creation of the quote + to: + $ref: '#/components/schemas/transferParty' + description: Information about the Payee in the proposed financial transaction. + amountType: + $ref: '#/components/schemas/amountType' + description: 'SEND for send amount, RECEIVE for receive amount.' + amount: + $ref: '#/components/schemas/money' + description: Depending on amountType. If SEND - The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction. If RECEIVE - The amount the Payee should receive, that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities. + currency: + $ref: '#/components/schemas/currency' + feesAmount: + $ref: '#/components/schemas/money' + description: The fees in the transaction. The fees element should be empty if fees should be non-disclosed. The fees element should be non-empty if fees should be disclosed. + feesCurrency: + $ref: '#/components/schemas/currency' + transactionType: + $ref: '#/components/schemas/transactionType' + description: Type of transaction for which the quote is requested. + initiator: + $ref: '#/components/schemas/initiator' + description: Specifies if the initiator of the transfer is the payer or payee + initiatorType: + $ref: '#/components/schemas/initiatorType' + description: Specifies the type of the transaction initiator + note: + type: string + minLength: 1 + maxLength: 128 + description: An optional note associated with the quote + + IndividualQuoteResult: + type: object + description: Data model for individual quote in a bulk quote response + properties: + quoteId: + $ref: '#/components/schemas/quoteId' + description: Identifies quote message. + transferAmount: + $ref: '#/components/schemas/money' + description: The amount of money that the Payer FSP should transfer to the Payee FSP + transferAmountCurrency: + $ref: '#/components/schemas/currency' + description: The currency of the transferAmount + payeeReceiveAmount: + $ref: '#/components/schemas/money' + description: The amount that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees + payeeReceiveAmountCurrency: + $ref: '#/components/schemas/currency' + description: The currency of the payeeReceiveAmount + payeeFspFeeAmount: + $ref: '#/components/schemas/money' + description: Payee FSP’s part of the transaction fee + payeeFspFeeAmountCurrency: + $ref: '#/components/schemas/currency' + description: The currency of the payeeFspFeeAmount + payeeFspCommissionAmount: + $ref: '#/components/schemas/money' + description: Transaction commission from the Payee FSP + payeeFspCommissionAmountCurrency: + $ref: '#/components/schemas/currency' + description: Currency of the payeeFspCommissionAmount + + bulkQuoteId: + pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ + type: string + description: A Mojaloop API bulk quote identifier (UUID) + + bulkTransferRequest: + type: object + required: + - bulkTransferId + - individualTransfers + properties: + bulkTransferId: + $ref: '#/components/schemas/bulkTransferId' + bulkQuote: + $ref: '#/components/schemas/bulkQuoteResponse' + from: + $ref: '#/components/schemas/transferParty' + individualTransfers: + type: array + minItems: 1 + maxItems: 1000 + items: + $ref: '#/components/schemas/IndividualTransfer' + + IndividualTransfer: + type: object + description: Data model for individual transfer in a bulk transfer request + required: + - transferId + - amount + - currency + properties: + transferId: + $ref: '#/components/schemas/transferId' + to: + $ref: '#/components/schemas/transferParty' + description: Information about the Payee in the proposed financial transaction. + amountType: + $ref: '#/components/schemas/amountType' + description: 'SEND for send amount, RECEIVE for receive amount.' + amount: + $ref: '#/components/schemas/money' + description: Depending on amountType. If SEND - The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction. If RECEIVE - The amount the Payee should receive, that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities. + currency: + $ref: '#/components/schemas/currency' + feesAmount: + $ref: '#/components/schemas/money' + description: The fees in the transaction. The fees element should be empty if fees should be non-disclosed. The fees element should be non-empty if fees should be disclosed. + feesCurrency: + $ref: '#/components/schemas/currency' + transactionType: + $ref: '#/components/schemas/transactionType' + description: Type of transaction for which the quote is requested. + initiator: + $ref: '#/components/schemas/initiator' + description: Specifies if the initiator of the transfer is the payer or payee + initiatorType: + $ref: '#/components/schemas/initiatorType' + description: Specifies the type of the transaction initiator + note: + type: string + minLength: 1 + maxLength: 128 + description: An optional note associated with the quote + + bulkTransferResponse: + type: object + required: + - homeTransactionId + properties: + bulkTransferId: + $ref: '#/components/schemas/bulkTransferId' + homeTransactionId: + type: string + description: Transaction ID from the DFSP backend, used to reconcile transactions between the switch and DFSP backend systems + from: + $ref: '#/components/schemas/transferParty' + individualTransfers: + type: array + minItems: 1 + maxItems: 1000 + items: + $ref: '#/components/schemas/IndividualTransfer' + + bulkTransferId: + pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ + type: string + description: A Mojaloop API transfer identifier (UUID) geoCode: type: object @@ -1147,6 +1614,7 @@ components: type: string pattern: ^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ description: The API data type Latitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. + longitude: type: string pattern: ^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$ @@ -1161,6 +1629,59 @@ components: message: type: string description: Error message text + + extensionList: + type: array + items: + $ref: '#/components/schemas/extensionItem' + minItems: 0 + maxItems: 16 + + extensionItem: + type: object + properties: + key: + type: string + minLength: 1 + maxLength: 32 + value: + type: string + minLength: 1 + maxLength: 128 + + transferState: + type: string + enum: + - RECEIVED + - RESERVED + - COMMITTED + - ABORTED + description: > + Below are the allowed values for the enumeration + - RECEIVED DFSP has received the transfer. + - RESERVED DFSP has reserved the transfer. + - COMMITTED DFSP has successfully performed the transfer. + - ABORTED DFSP has aborted the transfer due a rejection or failure to perform the transfer. + + fulfilNotification: + title: TransfersIDPatchResponse + type: object + description: PUT /transfers/{transferId} object + properties: + completedTimestamp: + $ref: '#/components/schemas/timestamp' + description: Time and date when the transaction was completed. + example: "2020-05-19T08:38:08.699-04:00" + transferState: + $ref: '#/components/schemas/transferState' + description: State of the transfer. + example: COMMITTED + extensionList: + $ref: '#/components/schemas/extensionList' + description: Optional extension, specific to deployment. + required: + - completedTimestamp + - transferState AuthenticationInfo: title: AuthenticationInfo diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index 69cfb5ff..90088afe 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -18,6 +18,9 @@ * Gates Foundation - Name Surname * Mowali + + * ModusBox + - Steven Oderayi -------------- ******/ 'use strict'; @@ -31,8 +34,8 @@ const { ApiErrorCodes } = require('../models/errors.js'); const getParticipantsByTypeAndId = async (ctx) => { try { - const { idValue, idType } = ctx.state.path.params; - const res = await ctx.state.model.party.get(idType, idValue); + const { idValue, idType, subIdValue } = ctx.state.path.params; + const res = await ctx.state.model.party.get(idType, idValue, subIdValue); if (!res) { ctx.response.body = ApiErrorCodes.ID_NOT_FOUND; ctx.response.status = 404; @@ -50,8 +53,8 @@ const getParticipantsByTypeAndId = async (ctx) => { const getPartiesByTypeAndId = async (ctx) => { // TODO: check that the provided type was MSISDN? Or just encode that in the API spec.. try { - const { idValue, idType } = ctx.state.path.params; - const res = await ctx.state.model.party.get(idType, idValue); + const { idValue, idType, subIdValue } = ctx.state.path.params; + const res = await ctx.state.model.party.get(idType, idValue, subIdValue); if (!res) { ctx.response.body = ApiErrorCodes.ID_NOT_FOUND; ctx.response.status = 404; @@ -106,6 +109,21 @@ const postTransfers = async (ctx) => { } }; +const putTransfersById = async (ctx) => { + try { + const res = await ctx.state.model.transfer.update(ctx.state.path.params.transferId, { + ...ctx.request.body, + }); + ctx.state.logger.log(`putTransfersById is returning body: ${util.inspect(res)}`); + ctx.response.body = ctx.request.body; + ctx.response.status = 200; + } catch (err) { + ctx.state.logger.log(`Error in putTransfersById: ${getStackOrInspect(err)}`); + ctx.response.body = ApiErrorCodes.SERVER_ERROR; + ctx.response.status = 500; + } +}; + const postQuotes = async (ctx) => { try { @@ -120,6 +138,36 @@ const postQuotes = async (ctx) => { } }; +const postBulkQuotes = async (ctx) => { + try { + const res = await ctx.state.model.bulkQuote.create(ctx.request.body); + ctx.state.logger.log(`postBulkQuotes is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; + } catch (err) { + ctx.state.logger.log(`Error in postBulkQuotes: ${getStackOrInspect(err)}`); + ctx.response.body = ApiErrorCodes.SERVER_ERROR; + ctx.response.status = 500; + } +}; + +const getBulkQuoteById = async (ctx) => { + try { + const { idValue } = ctx.state.path.params; + const res = await ctx.state.model.bulkQuote.get(idValue); + if (!res) { + ctx.response.body = ApiErrorCodes.ID_NOT_FOUND; + ctx.response.status = 404; + return; + } + ctx.response.body = res; + ctx.response.status = 200; + } catch (err) { + ctx.response.body = ApiErrorCodes.SERVER_ERROR; + ctx.response.status = 500; + } +}; + const postTransactionRequests = async (ctx) => { try { const res = await ctx.state.model.transactionrequest.create(ctx.request.body); @@ -133,6 +181,35 @@ const postTransactionRequests = async (ctx) => { } }; +const postBulkTransfers = async (ctx) => { + try { + const res = await ctx.state.model.bulkTransfer.create(ctx.request.body); + ctx.state.logger.log(`postBulkTransfers is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; + } catch (err) { + ctx.state.logger.log(`Error in postBulkTransfers: ${getStackOrInspect(err)}`); + ctx.response.body = ApiErrorCodes.SERVER_ERROR; + ctx.response.status = 500; + } +}; + +const getBulkTransferById = async (ctx) => { + try { + const { idValue } = ctx.state.path.params; + const res = await ctx.state.model.bulkTransfer.get(idValue); + if (!res) { + ctx.response.body = ApiErrorCodes.ID_NOT_FOUND; + ctx.response.status = 404; + return; + } + ctx.response.body = res; + ctx.response.status = 200; + } catch (err) { + ctx.response.body = ApiErrorCodes.SERVER_ERROR; + ctx.response.status = 500; + } +}; const healthCheck = async (ctx) => { ctx.response.status = 200; @@ -147,24 +224,45 @@ const map = { '/participants/{idType}/{idValue}': { get: getParticipantsByTypeAndId, }, + '/participants/{idType}/{idValue}/{subIdValue}': { + get: getParticipantsByTypeAndId, + }, '/parties/{idType}/{idValue}': { get: getPartiesByTypeAndId, }, + '/parties/{idType}/{idValue}/{subIdValue}': { + get: getPartiesByTypeAndId, + }, '/quoterequests': { post: postQuotes, }, + '/bulkQuotes': { + post: postBulkQuotes, + }, + '/bulkQuotes/{idValue}': { + get: getBulkQuoteById, + }, '/transactionrequests': { post: postTransactionRequests, }, '/transfers': { post: postTransfers, }, + '/bulkTransfers': { + post: postBulkTransfers, + }, + '/bulkTransfers/{idValue}': { + get: getBulkTransferById, + }, '/signchallenge': { post: getSignedChallenge, }, '/otp/{requestToPayId}': { get: getOTPById, }, + '/transfers/{transferId}': { + put: putTransfersById, + }, }; diff --git a/src/test-api/api.yaml b/src/test-api/api.yaml index 07e3c860..23c1f1d6 100644 --- a/src/test-api/api.yaml +++ b/src/test-api/api.yaml @@ -78,7 +78,62 @@ paths: description: Deletes a party responses: '204': - description: The party was created + description: The party was deleted + '500': + description: An error occured processing the request + parameters: + - name: idType + in: path + required: true + schema: + $ref: '#/components/schemas/idType' + - name: idValue + in: path + required: true + schema: + $ref: '#/components/schemas/idValue' + + /repository/parties/{idType}/{idValue}/{subIdValue}: + put: + description: Modifies a party (subId) + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Party' + responses: + '204': + description: Party was created + '400': + description: The request was malformed + '500': + description: An error occured processing the request + parameters: + - name: idType + in: path + required: true + schema: + $ref: '#/components/schemas/idType' + - name: idValue + in: path + required: true + schema: + $ref: '#/components/schemas/idValue' + - name: subIdValue + in: path + required: true + schema: + $ref: '#/components/schemas/subIdValue' + get: + description: Get an existing party + responses: + '200': + description: Party data is returned + delete: + description: Deletes a party + responses: + '204': + description: The party was deleted '500': description: An error occured processing the request parameters: @@ -92,13 +147,18 @@ paths: required: true schema: $ref: '#/components/schemas/idValue' + - name: subIdValue + in: path + required: true + schema: + $ref: '#/components/schemas/subIdValue' components: schemas: Scenario: title: Scenario type: object - description: An outbound transfer scenario + description: An outbound transfer, bulk transfer or bulk quote scenario required: - name - operation @@ -111,7 +171,7 @@ components: body: type: object description: >- - This object should be either a POST /transfers or PUT /transfers + This object should be either a POST /transfers, PUT /transfers, POST /bulkTransfers or POST /bulkQuotes request body as per the SDK outbound API specification params: $ref: '#/components/schemas/ScenarioOperationParameters' @@ -122,17 +182,32 @@ components: enum: - postTransfers - putTransfers + - postBulkTransfers + - postBulkQuotes ScenarioOperationParameters: - type: object description: Parameters to pass into the scenario operation - required: - - transferId - properties: - transferId: - type: string - description: >- - Transfer ID e.g. in the case of putTransfers operation this is the - ID of the transfer to complete + type: object + oneOf: + - properties: + transferId: + type: string + description: >- + Transfer ID e.g. in the case of putTransfers operation this is the + ID of the transfer to complete + required: + - transferId + - properties: + bulkTransferId: + type: string + description: Bulk transfer ID + required: + - bulkTransferId + - properties: + bulkQuoteId: + type: string + description: Bulk quote ID + required: + - bulkQuoteId Party: title: Party type: object @@ -171,6 +246,10 @@ components: type: string minLength: 1 maxLength: 128 + subIdValue: + type: string + minLength: 1 + maxLength: 128 extensionList: $ref: '#/components/schemas/ExtensionList' accounts: @@ -234,3 +313,7 @@ components: type: string minLength: 1 maxLength: 128 + subIdValue: + type: string + minLength: 1 + maxLength: 128 diff --git a/src/test-api/client.js b/src/test-api/client.js index a0abf93a..5def0c6f 100644 --- a/src/test-api/client.js +++ b/src/test-api/client.js @@ -61,4 +61,42 @@ const putTransfers = async (transferId, body) => { return res.json(); }; -module.exports = { postTransfers, putTransfers }; +/** + * Endpoint call to outbound bulk transfer request initiation + * + * @param {Object} body bulk transfer body + * @returns {Promise.} response + */ +const postBulkTransfers = async (body) => { + const res = await fetch(`${OUTBOUND_ENDPOINT}/bulkTransfers`, { + method: 'POST', + body: JSON.stringify(body), + headers: { 'Content-Type': 'application/json' }, + }); + + return res.json(); +}; + +/** + * Endpoint call to outbound bulk quote request initiation + * + * @param {Object} body bulk quote body + * @returns {Promise.} response + */ +const postBulkQuotes = async (body) => { + const res = await fetch(`${OUTBOUND_ENDPOINT}/bulkQuotes`, { + method: 'POST', + body: JSON.stringify(body), + headers: { 'Content-Type': 'application/json' }, + }); + + return res.json(); +}; + + +module.exports = { + postTransfers, + putTransfers, + postBulkTransfers, + postBulkQuotes, +}; diff --git a/src/test-api/handlers.js b/src/test-api/handlers.js index 0ed70538..b12e722c 100644 --- a/src/test-api/handlers.js +++ b/src/test-api/handlers.js @@ -24,13 +24,19 @@ const util = require('util'); const Mustache = require('mustache'); - -const { postTransfers, putTransfers } = require('./client'); +const { + postTransfers, + putTransfers, + postBulkTransfers, + postBulkQuotes, +} = require('./client'); const { ApiErrorCodes } = require('../models/errors'); const supportedOperations = { POST_TRANSFERS: 'postTransfers', PUT_TRANSFERS: 'putTransfers', + POST_BULK_TRANSFERS: 'postBulkTransfers', + POST_BULK_QUOTES: 'postBulkQuotes', }; @@ -70,13 +76,13 @@ const readParties = async (ctx) => { const readParty = async (ctx) => { try { - const { idValue, idType } = ctx.state.path.params; + const { idValue, idType, subIdValue } = ctx.state.path.params; if (!idValue || !idType) { ctx.response.body = ApiErrorCodes.MISSING_ID_VALUE; ctx.response.status = 400; return; } - const res = await ctx.state.model.party.get(idType, idValue); + const res = await ctx.state.model.party.get(idType, idValue, subIdValue); if (!res) { ctx.response.body = ''; ctx.response.status = 404; @@ -91,7 +97,7 @@ const readParty = async (ctx) => { }; const updateParty = async (ctx) => { - const { idValue, idType } = ctx.state.path.params; + const { idValue, idType, subIdValue } = ctx.state.path.params; const model = ctx.request.body; if (!idValue || !idType) { ctx.response.body = ApiErrorCodes.MISSING_ID_VALUE; @@ -100,7 +106,7 @@ const updateParty = async (ctx) => { } try { - await ctx.state.model.party.update(idType, idValue, model); + await ctx.state.model.party.update(model, idType, idValue, subIdValue); ctx.response.status = 204; return; } catch (err) { @@ -110,7 +116,7 @@ const updateParty = async (ctx) => { }; const deleteParty = async (ctx) => { - const { idValue, idType } = ctx.state.path.params; + const { idValue, idType, subIdValue } = ctx.state.path.params; if (!idValue || !idType) { ctx.response.body = ApiErrorCodes.MISSING_ID_VALUE; ctx.response.status = 500; @@ -118,7 +124,7 @@ const deleteParty = async (ctx) => { } try { - await ctx.state.model.party.delete(idType, idValue); + await ctx.state.model.party.delete(idType, idValue, subIdValue); ctx.response.status = 204; return; } catch (err) { @@ -173,6 +179,16 @@ const handleOps = async (logger, model, ops) => { const response = await model.putTransfers(renderedParams.transferId, renderedBody); acc[op.name] = { result: response }; } + + if (op.operation === supportedOperations.POST_BULK_TRANSFERS) { + const response = await model.postBulkTransfers(renderedBody); + acc[op.name] = { result: response }; + } + + if (op.operation === supportedOperations.POST_BULK_QUOTES) { + const response = await model.postBulkQuotes(renderedBody); + acc[op.name] = { result: response }; + } } catch (error) { acc[op.name] = { error }; } @@ -190,6 +206,8 @@ const handleScenarios = async (ctx) => { const res = await handleOps(ctx.state.logger, { postTransfers, putTransfers, + postBulkTransfers, + postBulkQuotes, }, ctx.request.body); ctx.state.logger.log(`Scenario operations returned: ${util.inspect(res)}`); @@ -222,6 +240,11 @@ const map = { delete: deleteParty, get: readParty, }, + '/repository/parties/{idType}/{idValue}/{subIdValue}': { + put: updateParty, + delete: deleteParty, + get: readParty, + }, }; diff --git a/src/test/admin.js b/src/test/admin.js index 5cc2179b..bb4b2474 100644 --- a/src/test/admin.js +++ b/src/test/admin.js @@ -30,7 +30,7 @@ const { party, idType, idValue } = require('./constants'); test.beforeEach(async (t) => { const model = new Model(); - await model.init(':memory:'); + await model.init({ databaseFilepath: ':memory:' }); // eslint-disable-next-line no-param-reassign t.context = { state: { model }, response: {} }; }); diff --git a/src/test/constants.js b/src/test/constants.js index 1df368b4..9ad9da8e 100644 --- a/src/test/constants.js +++ b/src/test/constants.js @@ -18,6 +18,9 @@ * Gates Foundation - Name Surname * Mowali + + * ModusBox + - Steven Oderayi -------------- ******/ 'use strict'; @@ -29,9 +32,11 @@ const uuid = require('uuid/v1'); const chance = new Chance(); const randName = chance.name({ suffix: true, middle: true }); const transferId = uuid(); +const bulkTransferId = uuid(); const transactionRequestId = uuid(); const idType = 'msisdn'; const idValue = uuid(); +const subIdValue = uuid(); const currency = '$'; const amount = 100; const amountType = 'SEND'; @@ -46,6 +51,18 @@ const party = { idType, idValue, }; + +const partyWithSubIdValue = { + displayName: randName, + firstName: randName.split(' ')[0] || '', + middleName: randName.split(' ')[1] || '', + lastName: randName.split(' ')[2] || '', + dateOfBirth: '1970-01-01T00:00:00.000Z', + idType, + idValue, + subIdValue, +}; + const partyCreate = { displayName: randName, firstName: randName.split(' ')[0] || '', @@ -78,6 +95,39 @@ const partyCreate = { ], }; +const partyCreateWithSubIdValue = { + displayName: randName, + firstName: randName.split(' ')[0] || '', + middleName: randName.split(' ')[1] || '', + lastName: randName.split(' ')[2] || '', + dateOfBirth: '1970-01-01T00:00:00.000Z', + idType, + idValue, + subIdValue, + extensionList: [ + { + key: 'accountType', + value: 'Wallet', + }, + { + key: 'accountNumber', + value: '12345343', + }, + ], + accounts: [ + { + currency: 'USD', + description: 'savings', + address: 'moja.green.e1f3c3e0-a00f-49b6-a331-280fdd1b2c32', + }, + { + currency: 'USD', + description: 'checking', + address: 'moja.green.6de1a4af-faca-4f08-ac21-f5e3a5203f49', + }, + ], +}; + const quote = { quoteId: idValue, @@ -100,6 +150,79 @@ const quote = { initiatorType: 'CONSUMER', }; +const newQuote = { + quoteId: uuid(), + transactionId: uuid(), + to: { + idType: 'MSISDN', + idValue: '0012345', + }, + from: { + idType: 'MSISDN', + idValue: '0067890', + }, + amountType: 'SEND', + amount: '100', + currency: 'USD', + feesAmount: '0.5', + feesCurrency: 'USD', + transactionType: 'TRANSFER', + initiator: 'PAYER', + initiatorType: 'CONSUMER', +}; + +const bulkQuote = { + bulkQuoteId: idValue, + from: { + idType: 'MSISDN', + idValue: '0067890', + }, + individualQuotes: [ + { + quoteId: idValue, + transactionId: uuid(), + to: { + idType: 'MSISDN', + idValue: '0012345', + }, + amountType: 'SEND', + amount: '100', + currency: 'USD', + feesAmount: '0.5', + feesCurrency: 'USD', + transactionType: 'TRANSFER', + initiator: 'PAYER', + initiatorType: 'CONSUMER', + }, + ], +}; + +const newBulkQuote = { + bulkQuoteId: uuid(), + from: { + idType: 'MSISDN', + idValue: '0067890', + }, + individualQuotes: [ + { + quoteId: uuid(), + transactionId: uuid(), + to: { + idType: 'MSISDN', + idValue: '0012345', + }, + amountType: 'SEND', + amount: '100', + currency: 'USD', + feesAmount: '0.5', + feesCurrency: 'USD', + transactionType: 'TRANSFER', + initiator: 'PAYER', + initiatorType: 'CONSUMER', + }, + ], +}; + const transactionrequest = { transactionRequestId, to: { @@ -186,27 +309,6 @@ const transfer = { transactionType, }; -const newQuote = { - quoteId: uuid(), - transactionId: uuid(), - to: { - idType: 'MSISDN', - idValue: '0012345', - }, - from: { - idType: 'MSISDN', - idValue: '0067890', - }, - amountType: 'SEND', - amount: '100', - currency: 'USD', - feesAmount: '0.5', - feesCurrency: 'USD', - transactionType: 'TRANSFER', - initiator: 'PAYER', - initiatorType: 'CONSUMER', -}; - const newTransfer = { transferId: uuid(), quote: { @@ -229,6 +331,70 @@ const newTransfer = { transactionType, }; +const bulkTransfer = { + bulkTransferId, + from: { + idType, + idValue, + }, + bulkQuote: { + bulkQuoteId: idValue, + individualQuotes: [ + { + quoteId: uuid(), + transactionId: randName, + transferAmount: amount, + transferAmountCurrency: currency, + }, + ], + }, + individualTransfers: [ + { + transferId: uuid(), + to: { + idType, + idValue: '67890', + }, + amountType, + currency, + amount, + transactionType, + }, + ], +}; + +const newBulkTransfer = { + bulkTransferId: uuid(), + from: { + idType, + idValue, + }, + bulkQuote: { + bulkQuoteId: uuid(), + individualQuotes: [ + { + quoteId: uuid(), + transactionId: randName, + transferAmount: amount, + transferAmountCurrency: currency, + }, + ], + }, + individualTransfers: [ + { + transferId: uuid(), + to: { + idType, + idValue: '67890', + }, + amountType, + currency, + amount, + transactionType, + }, + ], +}; + const transferWithoutQuote = { transferId, currency, @@ -243,16 +409,24 @@ test('constants', async (t) => { module.exports = { transfer, + newTransfer, + transferWithoutQuote, + bulkTransfer, + newBulkTransfer, + bulkTransferId, quote, + newQuote, + bulkQuote, + newBulkQuote, transactionrequest, + transactionRequestId, party, partyCreate, - newQuote, - newTransfer, - transferWithoutQuote, idType, idValue, transferId, + partyWithSubIdValue, + partyCreateWithSubIdValue, + subIdValue, authorizationRequest, - transactionRequestId, }; diff --git a/src/test/model.js b/src/test/model.js index dcb55242..d73abf92 100644 --- a/src/test/model.js +++ b/src/test/model.js @@ -18,6 +18,9 @@ * Gates Foundation - Name Surname * Mowali + + * ModusBox + - Steven Oderayi -------------- ******/ 'use strict'; @@ -25,14 +28,18 @@ const test = require('ava'); const Model = require('../models/model'); + +const { cloneDeep } = require('./unit/TestUtils'); + const { - transfer, quote, transactionrequest, party, newQuote, newTransfer, idType, idValue, partyCreate, - transferId, transactionRequestId, + transfer, quote, newQuote, bulkQuote, newBulkQuote, transactionrequest, party, newTransfer, + bulkTransfer, newBulkTransfer, bulkTransferId, idType, idValue, partyCreate, transferId, + transactionRequestId, partyWithSubIdValue, partyCreateWithSubIdValue, subIdValue, } = require('./constants'); test.beforeEach(async (t) => { const model = new Model(); - await model.init(':memory:'); + await model.init({ databaseFilepath: ':memory:' }); // eslint-disable-next-line no-param-reassign t.context = { model }; }); @@ -61,6 +68,18 @@ test('create and retrieve all parties', async (t) => { } t.pass(); }); + +test('create and retrieve all parties with subIdValue', async (t) => { + const { model } = t.context; + + await model.party.create(partyCreateWithSubIdValue); + const res = await model.party.getAll(); + if (!res) { + t.fail('Result not found'); + } + t.pass(); +}); + test('create and retrieve all parties duplicates', async (t) => { const { model } = t.context; await model.party.create(partyCreate); @@ -83,6 +102,17 @@ test('create and retrieve a party', async (t) => { t.pass(); }); +test('create and retrieve a party with subIdValue', async (t) => { + const { model } = t.context; + + await model.party.create(partyCreateWithSubIdValue); + const res = await model.party.get(idType, idValue, subIdValue); + if (!res) { + t.fail('Result not found'); + } + t.pass(); +}); + test('create and update a party', async (t) => { const { model } = t.context; const newParty = { @@ -118,11 +148,77 @@ test('create and update a party', async (t) => { }; await model.party.create(partyCreate); const orig = await model.party.get(idType, idValue); - await model.party.update(idType, idValue, newParty); + await model.party.update(newParty, idType, idValue); + const changed = await model.party.get(idType, idValue); + t.notDeepEqual({ orig }, { changed }); +}); + +test('create and update a party without extensionList', async (t) => { + const { model } = t.context; + const newParty = { + displayName: 'randName', + firstName: 'hello', + middleName: 'world', + lastName: 'lambda', + dateOfBirth: '1970-01-01T00:00:00.000Z', + idType, + idValue, + }; + await model.party.create(partyCreate); + const orig = await model.party.get(idType, idValue); + await model.party.update(newParty, idType, idValue); const changed = await model.party.get(idType, idValue); t.notDeepEqual({ orig }, { changed }); }); +test('create and update a party with subIdValue', async (t) => { + const { model } = t.context; + const newParty = { + displayName: 'randName', + firstName: 'hello', + middleName: 'world', + lastName: 'lambda', + dateOfBirth: '1970-01-01T00:00:00.000Z', + idType, + idValue, + subIdValue, + extensionList: [ + { + key: 'accountType', + value: 'Wallet', + }, + { + key: 'accountNumber', + value: '12345343', + }, + ], + }; + await model.party.create(partyCreateWithSubIdValue); + const orig = await model.party.get(idType, idValue, subIdValue); + await model.party.update(newParty, idType, idValue, subIdValue); + const changed = await model.party.get(idType, idValue, subIdValue); + t.notDeepEqual({ orig }, { changed }); +}); + +test('create and update a party with subIdValue without extensionList', async (t) => { + const { model } = t.context; + const newParty = { + displayName: 'randName', + firstName: 'hello', + middleName: 'world', + lastName: 'lambda', + dateOfBirth: '1970-01-01T00:00:00.000Z', + idType, + idValue, + subIdValue, + }; + await model.party.create(partyWithSubIdValue); + const orig = await model.party.get(idType, idValue, subIdValue); + await model.party.update(newParty, idType, idValue, subIdValue); + const changed = await model.party.get(idType, idValue, subIdValue); + t.notDeepEqual({ orig }, { changed }); +}); + test('retrieve a participant', async (t) => { const { model } = t.context; await model.party.create(party); @@ -130,6 +226,13 @@ test('retrieve a participant', async (t) => { t.truthy(res); }); +test('retrieve a participant with subIdValue', async (t) => { + const { model } = t.context; + await model.party.create(partyWithSubIdValue); + const res = await model.party.get(idType, idValue, subIdValue); + t.truthy(res); +}); + test('create and delete a party', async (t) => { const { model } = t.context; await model.party.create(partyCreate); @@ -139,6 +242,15 @@ test('create and delete a party', async (t) => { t.is(deleted, undefined); }); +test('create and delete a party with subIdValue', async (t) => { + const { model } = t.context; + await model.party.create(partyCreateWithSubIdValue); + await model.party.get(idType, idValue, subIdValue); + await model.party.delete(idType, idValue, subIdValue); + const deleted = await model.party.get(idType, idValue, subIdValue); + t.is(deleted, undefined); +}); + test('should be undefined for non existing participant', async (t) => { const { model } = t.context; const res = await model.party.get('hello', '000000'); @@ -226,6 +338,77 @@ test('create and delete a quote', async (t) => { t.is(deleted, undefined); }); +test('create a bulk quote', async (t) => { + await t.context.model.bulkQuote.create(cloneDeep(bulkQuote)); + t.pass(); +}); + +test('create and retrieve a bulk quote', async (t) => { + const { model } = t.context; + + await model.bulkQuote.create(cloneDeep(bulkQuote)); + const res = await model.bulkQuote.get(idValue); + + if (!res) { + t.fail('Result not found'); + } + + t.pass(); +}); + +test('created bulk quote has correct fees', async (t) => { + const { model } = t.context; + + const bq = await model.bulkQuote.create(cloneDeep(bulkQuote)); + const q = bq.individualQuoteResults[0]; + + if (q.payeeFspFeeAmount !== '5') { + return t.fail(`Fee is ${q.payeeFspFeeAmount}`); + } + if (q.payeeFspCommissionAmount !== '5') { + return t.fail(`Fee is ${q.payeeFspCommissionAmount}`); + } + + return t.pass(); +}); + +test('created bulk quote has correct fees when transfer amounts is small', async (t) => { + const { model } = t.context; + + const smq = cloneDeep(bulkQuote); + smq.individualQuotes[0].amount = 1; + const bq = await model.bulkQuote.create(smq); + const q = bq.individualQuoteResults[0]; + + if (q.payeeFspFeeAmount !== '0') { + return t.fail(`Fee is ${q.payeeFspFeeAmount}`); + } + if (q.payeeFspCommissionAmount !== '0') { + return t.fail(`Fee is ${q.payeeFspCommissionAmount}`); + } + + return t.pass(); +}); + +test('create and update a bulk quote', async (t) => { + const { model } = t.context; + + await model.bulkQuote.create(cloneDeep(bulkQuote)); + const orig = await model.bulkQuote.get(idValue); + await model.bulkQuote.update(idValue, cloneDeep(newBulkQuote)); + const changed = await model.bulkQuote.get(idValue); + t.notDeepEqual({ orig }, { changed }); +}); + +test('create and delete a bulk quote', async (t) => { + const { model } = t.context; + await model.bulkQuote.create(cloneDeep(bulkQuote)); + await model.bulkQuote.get(idValue); + await model.bulkQuote.delete(idValue); + const deleted = await model.bulkQuote.get(idValue); + t.is(deleted, undefined); +}); + test('create a transfer', async (t) => { await t.context.model.transfer.create(transfer); t.pass(); @@ -261,6 +444,36 @@ test('create and delete a transfer', async (t) => { t.is(deleted, undefined); }); +test('create and retrieve a bulk transfer', async (t) => { + const { model } = t.context; + + await model.bulkTransfer.create(cloneDeep(bulkTransfer)); + const res = await model.bulkTransfer.get(bulkTransferId); + if (!res) { + t.fail('Result not found'); + } + t.pass(); +}); + +test('create and update a bulk transfer', async (t) => { + const { model } = t.context; + + await model.bulkTransfer.create(cloneDeep(bulkTransfer)); + const orig = await model.bulkTransfer.get(idValue); + await model.bulkTransfer.update(idValue, cloneDeep(newBulkTransfer)); + const changed = await model.bulkTransfer.get(idValue); + t.notDeepEqual({ orig }, { changed }); +}); + +test('create and delete a bulkTransfer', async (t) => { + const { model } = t.context; + await model.bulkTransfer.create(cloneDeep(bulkTransfer)); + await model.bulkTransfer.get(bulkTransferId); + await model.bulkTransfer.delete(bulkTransferId); + const deleted = await model.bulkTransfer.get(bulkTransferId); + t.is(deleted, undefined); +}); + test('create a transactionrequest', async (t) => { await t.context.model.transactionrequest.create(transactionrequest); t.pass(); @@ -298,7 +511,7 @@ test('throws if we try to init the db incorrectly', async (t) => { }); // Assert - t.is(error.message, 'TypeError: Argument 0 must be a string', 'Invalid error message.'); + t.is(error.message, 'Cannot destructure property \'databaseFilepath\' of \'undefined\' as it is undefined.', 'Invalid error message.'); }); test('does nothing if trying to close a non existent db', async (t) => { diff --git a/src/test/reports.js b/src/test/reports.js index ccf903bd..a6156437 100644 --- a/src/test/reports.js +++ b/src/test/reports.js @@ -39,7 +39,7 @@ const validQuerystring = stringify({ START_DATE_TIME: '2019-05-20T21:20:56', END const nonFindableQuerystring = stringify({ START_DATE_TIME: '2019-05-19T21:20:00', END_DATE_TIME: '2019-05-20T21:20:56' }); test.before(async (t) => { - await model.init(process.env.MODEL_DATABASE); + await model.init({ databaseFilepath: process.env.MODEL_DATABASE }); Array.from({ length: 10 }).forEach(async (x, i) => { quote.quoteId = uuid(); await model.quote.create(quote); diff --git a/src/test/simulator.js b/src/test/simulator.js index 4851fa28..c2ad12ef 100644 --- a/src/test/simulator.js +++ b/src/test/simulator.js @@ -18,24 +18,27 @@ * Gates Foundation - Name Surname * Mowali + + * ModusBox + - Steven Oderayi -------------- ******/ 'use strict'; const test = require('ava'); - +const { cloneDeep } = require('./unit/TestUtils'); const Model = require('../models/model'); const { map } = require('../simulator/handlers'); const { transfer, transferWithoutQuote, quote, transactionrequest, party, idType, idValue, - transactionRequestId, authorizationRequest, + transactionRequestId, bulkQuote, bulkTransfer, bulkTransferId, authorizationRequest, } = require('./constants'); const { ApiErrorCodes } = require('../models/errors'); test.beforeEach(async (t) => { const model = new Model(); - await model.init(':memory:'); + await model.init({ databaseFilepath: ':memory:' }); // eslint-disable-next-line no-param-reassign t.context = { state: { model, logger: console }, response: {}, @@ -71,6 +74,23 @@ test('create a quote', async (t) => { t.is(t.context.response.status, 200); }); +test('create a bulk quote', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { body: cloneDeep(bulkQuote) }; + await map['/bulkQuotes'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 200); +}); + +test('get a bulk quote', async (t) => { + await t.context.state.model.bulkQuote.create(bulkQuote); + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { idValue } }; + await map['/bulkQuotes/{idValue}'].get(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 200); +}); + test('create a transfer', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { body: transfer }; @@ -79,6 +99,23 @@ test('create a transfer', async (t) => { t.is(t.context.response.status, 200); }); +test('create a bulk transfer', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { body: cloneDeep(bulkTransfer) }; + await map['/bulkTransfers'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 200); +}); + +test('get a bulk transfer', async (t) => { + await t.context.state.model.bulkTransfer.create(bulkTransfer); + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { idValue: bulkTransferId } }; + await map['/bulkTransfers/{idValue}'].get(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 200); +}); + test('create a transactionrequest', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { body: transactionrequest }; @@ -139,6 +176,22 @@ test('should return 500 while posting a non valid transfer object', async (t) => t.is(t.context.response.status, 500); }); +test('should return 500 while posting a non valid bulk quote object', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { body: { hello: 'world' } }; + await map['/bulkQuotes'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 500); +}); + +test('should return 500 while posting a non valid bulk transfer object', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { body: { hello: 'world' } }; + await map['/bulkTransfers'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 500); +}); + test('should return 404 while getting a non existing participant', async (t) => { // eslint-disable-next-line no-param-reassign t.context.state.path = { params: { idValue: 'invalidID0001', idType: 'invalidType' } }; @@ -147,6 +200,23 @@ test('should return 404 while getting a non existing participant', async (t) => t.is(t.context.response.status, 404); }); +test('should return 404 while getting a non existent bulk quote', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { idValue: 'invalidID0001' } }; + await map['/bulkQuotes/{idValue}'].get(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 404); +}); + + +test('should return 404 while getting a non existent bulk transfer', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { idValue: 'invalidID0001' } }; + await map['/bulkTransfers/{idValue}'].get(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 404); +}); + test('should return a valid health check', async (t) => { // Arrange // eslint-disable-next-line no-param-reassign @@ -184,3 +254,41 @@ test('postQuotes should handle 500 errors', async (t) => { t.deepEqual(t.context.response, expected, 'Response did not match expected'); t.pass(); }); + +test('postBulkQuotes should handle 500 errors', async (t) => { + // Arrange + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { idValue, idType } }; + // eslint-disable-next-line no-throw-literal, no-param-reassign + t.context.state.model.bulkQuote.create = () => { throw 'Bad error!'; }; + // eslint-disable-next-line no-param-reassign + t.context.request = { body: cloneDeep(bulkQuote) }; + + const expected = { + body: ApiErrorCodes.SERVER_ERROR, + status: 500, + }; + + // Act + await map['/bulkQuotes'].post(t.context); + // Assert + t.deepEqual(t.context.response, expected, 'Response did not match expected'); + t.pass(); +}); + +test('putTransfersById should handle request', async (t) => { + // Arrange + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { transferId: '1234' } }; + // eslint-disable-next-line no-throw-literal, no-param-reassign + t.context.request = { + body: { + completedTimestamp: '2017-11-15T14:16:09.663+01:00', + transferState: 'COMMITTED', + }, + }; + await map['/transfers/{transferId}'].put(t.context); + const expected = t.context.request.body; + t.deepEqual(t.context.response, { body: { ...expected }, status: 200 }, 'response is received'); + t.pass(); +}); diff --git a/src/test/test-api.js b/src/test/test-api.js index eb79232c..3cc5ec4b 100644 --- a/src/test/test-api.js +++ b/src/test/test-api.js @@ -18,49 +18,124 @@ * Gates Foundation - Name Surname * Mowali + + * ModusBox + - Steven Oderayi -------------- ******/ 'use strict'; const test = require('ava'); -const Model = require('../../src/models/model'); +const Model = require('../models/model'); const handlers = require('../test-api/handlers'); const { ops, party, partyCreate } = require('./constants'); -const testOps = [{ - name: 'scenario1', - operation: 'postTransfers', - body: { - from: { - displayName: 'James Bush', - idType: 'MSISDN', - idValue: '447710066017', +const testOps = [ + { + name: 'scenario1', + operation: 'postTransfers', + body: { + from: { + displayName: 'James Bush', + idType: 'MSISDN', + idValue: '447710066017', + }, + to: { + idType: 'MSISDN', + idValue: '447710066018', + }, + amountType: 'SEND', + currency: 'USD', + amount: '100', + transactionType: 'TRANSFER', + note: 'test payment', + homeTransactionId: '123ABC', + }, + }, + { + name: 'scenario2', + operation: 'putTransfers', + params: { + transferId: '{{scenario1.result.transferId}}', }, - to: { - idType: 'MSISDN', - idValue: '447710066018', + body: { + acceptQuote: true, }, - amountType: 'SEND', - currency: 'USD', - amount: '100', - transactionType: 'TRANSFER', - note: 'test payment', - homeTransactionId: '123ABC', }, -}, { - name: 'scenario2', - operation: 'putTransfers', - params: { - transferId: '{{scenario1.result.transferId}}', + { + name: 'scenario3', + operation: 'postBulkTransfers', + body: { + from: { + displayName: 'Steven Oderayi', + idType: 'MSISDN', + idValue: '447710066028', + }, + individualTransfers: [ + { + to: { + idType: 'MSISDN', + idValue: '447710066018', + }, + amountType: 'SEND', + currency: 'USD', + amount: '100', + transactionType: 'TRANSFER', + note: 'test payment', + homeTransactionId: '123ABC', + }, + ], + }, }, - body: { - acceptQuote: true, + { + name: 'scenario4', + operation: 'postBulkQuotes', + body: { + from: { + displayName: 'Steven Oderayi', + idType: 'MSISDN', + idValue: '447710066028', + }, + individualQuotes: [ + { + quoteId: '8746736546', + transactionId: '5678390498', + to: { + idType: 'MSISDN', + idValue: '447710066018', + }, + currency: 'USD', + amount: '100', + note: 'test payment', + }, + ], + }, }, -}]; + +]; + +const preconfiguredParties = [ + { + ...party, + idValue: '123457', + }, + { + ...party, + idValue: '123458', + }, + { + ...party, + idValue: '123459', + }, + { + ...party, + idValue: '123456', + }, +]; test.beforeEach(async (t) => { const model = new Model(); - await model.init(':memory:'); + await model.init({ databaseFilepath: ':memory:', parties: preconfiguredParties }); // eslint-disable-next-line no-param-reassign t.context = { state: { model, logger: console }, response: {} }; }); @@ -69,6 +144,12 @@ test.afterEach(async (t) => { await t.context.state.model.close(); }); +test.only('preconfigured parties should pre-exist', async (t) => { + await handlers.map['/repository/parties'].get(t.context); + const byId = (a, b) => Number(a.idValue) - Number(b.idValue); + t.deepEqual(t.context.response.body.sort(byId), preconfiguredParties.sort(byId)); +}); + test('should return 200 when reading a party', async (t) => { // eslint-disable-next-line no-param-reassign await handlers.map['/repository/parties'].get(t.context); @@ -121,20 +202,31 @@ test('should call outbound transfers model and pass on results to next operation putTransfers: async (transferId) => Promise.resolve({ transferId, }), + postBulkTransfers: async () => Promise.resolve({ + bulkTransferId: '1234567890', + }), + postBulkQuotes: async () => Promise.resolve({ + bulkQuoteId: '1234567890', + }), }; const result = await handlers.handleOps(console, model, testOps); t.truthy(result.scenario1); t.truthy(result.scenario2); + t.truthy(result.scenario3); + t.truthy(result.scenario4); t.truthy(result.scenario1.result); t.truthy(result.scenario2.result); + t.truthy(result.scenario3.result); + t.truthy(result.scenario4.result); t.is(result.scenario1.result.transferId, '12345ABCDEF'); t.is(result.scenario2.result.transferId, '12345ABCDEF'); + t.is(result.scenario3.result.bulkTransferId, '1234567890'); + t.is(result.scenario4.result.bulkQuoteId, '1234567890'); }); - test('should return 500 when sending a non valid ops', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { body: { hello: 'world' } }; diff --git a/src/test/unit/TestUtils.js b/src/test/unit/TestUtils.js index a8b5e8e8..9b2b6921 100644 --- a/src/test/unit/TestUtils.js +++ b/src/test/unit/TestUtils.js @@ -4,6 +4,19 @@ const testLogger = (t) => ({ push: () => ({ log: (message) => t.log(message) }), }); +/** + * Makes a deep clone of an object or array. + * + * Note that this will only copy JSON-compatible properties, + * things like function etc. will be lost. + * This function should only be used to clone simple objects with + * some depth which cannot be successfully cloned using other means. + * + * @returns {Object} clone of argument. + */ +const cloneDeep = (o) => JSON.parse(JSON.stringify(o)); + module.exports = { testLogger, + cloneDeep, }; diff --git a/src/test/unit/config.test.js b/src/test/unit/config.test.js index aa945afa..53311612 100644 --- a/src/test/unit/config.test.js +++ b/src/test/unit/config.test.js @@ -19,13 +19,16 @@ - Name Surname * Vessels Tech - Lewis Daly + + * ModusBox + - Steven Oderayi -------------- ******/ 'use strict'; const test = require('ava'); const { setConfig, getConfig } = require('../../config'); - +const { party } = require('../constants'); // Note: these were originally 3 different tests, which I had to combine into 1 // because of the way that ava tries to run the tests in paralell, which was causing @@ -36,14 +39,20 @@ test('Sets the basic config', async (t) => { const env = { MUTUAL_TLS_ENABLED: 'false', HTTPS_ENABLED: 'false', + PARTIES: JSON.stringify([party, party, party]), }; const expected = { - tls: - { + tls: { enabled: false, mutualTLS: { enabled: false }, creds: { ca: null, cert: null, key: null }, }, + ports: { + simulatorApi: 3000, + reportApi: 3002, + testApi: 3003, + }, + parties: [party, party, party], }; // Act From c6e1a23e15ff8d94c3bb2407165c9faff163953f Mon Sep 17 00:00:00 2001 From: sridharvoruganti <36686863+sridharvoruganti@users.noreply.github.com> Date: Wed, 10 Mar 2021 19:44:04 +0530 Subject: [PATCH 10/34] feat(api): add get /accounts/{ID} endpoint (#90) --- src/audit-resolve.json | 24 ++++++++++++------------ src/simulator/api.yaml | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/audit-resolve.json b/src/audit-resolve.json index b94cd3e0..d28ff97c 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -7,33 +7,33 @@ }, "1589|sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1607553157718, - "expiresAt": 1610145105148 + "madeAt": 1615383991700, + "expiresAt": 1617975978786 }, "1589|00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1607553157718, - "expiresAt": 1610145105148 + "madeAt": 1615383991701, + "expiresAt": 1617975978786 }, "1589|00unidentified>00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1607553157718, - "expiresAt": 1610145105148 + "madeAt": 1615383991701, + "expiresAt": 1617975978786 }, "1589|ava>update-notifier>latest-version>package-json>registry-auth-token>rc>ini": { "decision": "ignore", - "madeAt": 1607553157718, - "expiresAt": 1610145105148 + "madeAt": 1615383991701, + "expiresAt": 1617975978786 }, "1589|ava>update-notifier>latest-version>package-json>registry-url>rc>ini": { "decision": "ignore", - "madeAt": 1607553157718, - "expiresAt": 1610145105148 + "madeAt": 1615383991701, + "expiresAt": 1617975978786 }, "1589|ava>update-notifier>is-installed-globally>global-dirs>ini": { "decision": "ignore", - "madeAt": 1607553157718, - "expiresAt": 1610145105148 + "madeAt": 1615383991701, + "expiresAt": 1617975978786 } }, "rules": {}, diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 6908aaf3..37b579d3 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -548,6 +548,40 @@ paths: application/json: schema: $ref: '#/components/schemas/errorResponse' + /accounts/{ID}: + get: + operationId: GetAccountsByUserId + summary: GetAccountsByUserId + description: | + The HTTP request `GET /accounts/{ID}` is used to retrieve the list of potential accounts available for linking. + tags: + - accounts + parameters: + - name: ID + in: path + required: true + schema: + type: string + description: The user identifier value. + responses: + 200: + description: Response containing details of the user accounts + content: + application/json: + schema: + type: object + 400: + description: 'invalid request' + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: 'internal server error' + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' components: schemas: @@ -1731,4 +1765,3 @@ components: entered the authentication value. - REJECTED Consumer rejected the transaction. - RESEND Consumer requested to resend the authentication value. - From 9400256cdbc63a512cfff9c450890451b3a276b2 Mon Sep 17 00:00:00 2001 From: sridharvoruganti <36686863+sridharvoruganti@users.noreply.github.com> Date: Thu, 11 Mar 2021 12:06:26 +0530 Subject: [PATCH 11/34] chore: add accounts handler and update API def (#91) * chore: add accounts handler and update API def * chore: improve test coverage --- src/simulator/api.yaml | 33 +++++++++++++++++++++++++++++++-- src/simulator/handlers.js | 16 ++++++++++++++++ src/test/simulator.js | 8 ++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 37b579d3..df5339bb 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -555,7 +555,7 @@ paths: description: | The HTTP request `GET /accounts/{ID}` is used to retrieve the list of potential accounts available for linking. tags: - - accounts + - Accounts parameters: - name: ID in: path @@ -569,7 +569,7 @@ paths: content: application/json: schema: - type: object + $ref: '#/components/schemas/AccountsIDPutResponse' 400: description: 'invalid request' content: @@ -1683,6 +1683,16 @@ components: minLength: 1 maxLength: 128 + accountAddress: + type: string + description: | + A long-lived unique account identifier provided by the DFSP. This MUST NOT + be Bank Account Number or anything that may expose a User's private bank + account information. + pattern: '^([0-9A-Za-z_~\-\.]+[0-9A-Za-z_~\-])$' + minLength: 1 + maxLength: 1023 + transferState: type: string enum: @@ -1765,3 +1775,22 @@ components: entered the authentication value. - REJECTED Consumer rejected the transaction. - RESEND Consumer requested to resend the authentication value. + + AccountsIDPutResponse: + title: AccountsIDPutResponse + type: array + items: + type: object + description: | + `GET /accounts/{ID}` response. + properties: + accountNickname: + $ref: '#/components/schemas/accountAddress' + id: + $ref: '#/components/schemas/accountAddress' + currency: + $ref: '#/components/schemas/currency' + required: + - accountNickname + - id + - currency \ No newline at end of file diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index 90088afe..c1fbca7e 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -216,6 +216,19 @@ const healthCheck = async (ctx) => { ctx.response.body = ''; }; +const getAccountsByUserId = async (ctx) => { + try { + const { ID } = ctx.state.path.params; + // if rules not configured, return ID not found error + ctx.state.logger.log(`getAccountsByUserId rules not configured for : ${ID}`); + ctx.response.body = ApiErrorCodes.ID_NOT_FOUND; + ctx.response.status = 404; + return; + } catch (err) { + ctx.response.body = ApiErrorCodes.SERVER_ERROR; + ctx.response.status = 500; + } +}; const map = { '/': { @@ -263,6 +276,9 @@ const map = { '/transfers/{transferId}': { put: putTransfersById, }, + '/accounts/{ID}': { + get: getAccountsByUserId, + }, }; diff --git a/src/test/simulator.js b/src/test/simulator.js index c2ad12ef..4495f64d 100644 --- a/src/test/simulator.js +++ b/src/test/simulator.js @@ -57,6 +57,14 @@ test('get an otp', async (t) => { t.is(t.context.response.status, 200); }); +test('get accounts by user Id', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { ID: 'test123' } }; + await map['/accounts/{ID}'].get(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 404); +}); + test('get a party', async (t) => { await t.context.state.model.party.create(party); // eslint-disable-next-line no-param-reassign From ef1c0348172d3823ec13e2557b16342fd0e97e4c Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Tue, 30 Mar 2021 06:50:33 -0500 Subject: [PATCH 12/34] feat: add dfsp backend endpoints for authentication testing (#92) * feat: add endpoints for authentication testing * chore: fix interface * chore: fix audit check * chore: change path * chore: fix coverage * chore: fix test --- src/audit-resolve.json | 14 ++- src/package-lock.json | 7 +- src/simulator/api.yaml | 241 +++++++++++++++++++++++++++++--------- src/simulator/handlers.js | 42 +++++++ src/test/simulator.js | 37 ++++++ 5 files changed, 281 insertions(+), 60 deletions(-) diff --git a/src/audit-resolve.json b/src/audit-resolve.json index d28ff97c..cea3d051 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -34,8 +34,20 @@ "decision": "ignore", "madeAt": 1615383991701, "expiresAt": 1617975978786 + }, + "1654|ava>yargs>y18n": { + "decision": "fix", + "madeAt": 1617075431111 + }, + "1654|nyc>yargs>y18n": { + "decision": "fix", + "madeAt": 1617075431111 + }, + "1654|npm-audit-resolver>yargs-unparser>yargs>y18n": { + "decision": "fix", + "madeAt": 1617075431111 } }, "rules": {}, "version": 1 -} +} \ No newline at end of file diff --git a/src/package-lock.json b/src/package-lock.json index f74dde54..70a83e81 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -5788,10 +5788,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" }, "yallist": { "version": "3.1.1", diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index df5339bb..ce8f88fc 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -296,7 +296,7 @@ paths: /otp/{requestToPayId}: get: - summary: Requests OTP + summary: Requests OTP tags: - OTP parameters: @@ -326,7 +326,7 @@ paths: application/json: schema: $ref: '#/components/schemas/errorResponse' - + /bulkQuotes: post: summary: Requests a bulk quote @@ -455,7 +455,7 @@ paths: schema: $ref: '#/components/schemas/errorResponse' - + /signchallenge: post: summary: Requests a signed challenge @@ -569,7 +569,76 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/AccountsIDPutResponse' + $ref: '#/components/schemas/AccountsIDPutResponse' + 400: + description: 'invalid request' + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: 'internal server error' + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + /validateOTP: + post: + operationId: PostValidateOTP + summary: PostValidateOTP + description: | + The HTTP request `POST /validateOTP` is used to validate an auth token from a PISP for authentication. + tags: + - validateOTP + requestBody: + description: An auth token and a consent request id. + required: true + content: + application/json: + schema: + type: object + responses: + 200: + description: Response containing if the auth token is valid or not. + content: + application/json: + schema: + $ref: '#/components/schemas/ValidateOTPResponse' + 400: + description: 'invalid request' + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: 'internal server error' + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + + /scopes/{ID}: + get: + operationId: GetScopesById + summary: GetScopesById + description: | + The HTTP request `GET /scopes/{ID}` is used to retrieve granted scopes for a specified consent request id. + tags: + - scopes + parameters: + - name: ID + in: path + required: true + schema: + type: string + description: The consent request identifier value. + responses: + 200: + description: Response containing a list of accounts and granted scopes. + content: + application/json: + schema: + $ref: '#/components/schemas/ScopesIdResponse' 400: description: 'invalid request' content: @@ -584,7 +653,7 @@ paths: $ref: '#/components/schemas/errorResponse' components: schemas: - + quoteRequest: type: object description: A request for a quote for transfer from the DFSP backend @@ -697,18 +766,18 @@ components: type: string description: An ISO-8601 formatted timestamp pattern: ^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:(\.\d{3}))(?:Z|[+-][01]\d:[0-5]\d)$ - + dateOfBirth: type: string description: Date of birth in the form YYYY-MM-DD pattern: ^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$ - + initiator: type: string enum: - PAYER - PAYEE - + initiatorType: type: string enum: @@ -716,7 +785,7 @@ components: - AGENT - BUSINESS - DEVICE - + quoteResponse: type: object description: A response to a request for a quote @@ -738,7 +807,7 @@ components: transferAmountCurrency: $ref: '#/components/schemas/currency' description: The currency of the transferAmount - payeeReceiveAmount: + payeeReceiveAmount: $ref: '#/components/schemas/money' description: The amount that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees payeeReceiveAmountCurrency: @@ -748,13 +817,13 @@ components: $ref: '#/components/schemas/money' description: Payee FSP’s part of the transaction fee payeeFspFeeAmountCurrency: - $ref: '#/components/schemas/currency' + $ref: '#/components/schemas/currency' description: The currency of the payeeFspFeeAmount payeeFspCommissionAmount: $ref: '#/components/schemas/money' description: Transaction commission from the Payee FSP payeeFspCommissionAmountCurrency: - $ref: '#/components/schemas/currency' + $ref: '#/components/schemas/currency' description: Currency of the payeeFspCommissionAmount expiration: $ref: '#/components/schemas/timestamp' @@ -762,7 +831,7 @@ components: geoCode: $ref: '#/components/schemas/geoCode' description: Longitude and Latitude of the Payee. Can be used to detect fraud - + transactionRequestResponse: type: object description: A response to a request for a quote @@ -782,12 +851,12 @@ components: properties: fspId: $ref: '#/components/schemas/fspId' - + fspId: type: string minLength: 1 maxLength: 32 - + payerType: type: string enum: @@ -795,13 +864,13 @@ components: - AGENT - BUSINESS - DEVICE - + amountType: type: string enum: - SEND - RECEIVE - + transactionType: type: string enum: @@ -816,7 +885,7 @@ components: - PENDING - ACCEPTED - REJECTED - + transferRequest: type: object required: @@ -866,21 +935,21 @@ components: description: Sequential counter used for cloning detection. Present only for U2F authentication. required: - pinValue - - counter + - counter U2FPIN: title: U2FPIN type: string pattern: ^\S{1,64}$ minLength: 1 maxLength: 64 - description: U2F challenge-response, where payer FSP verifies if the response provided by end-user device matches the previously registered key. + description: U2F challenge-response, where payer FSP verifies if the response provided by end-user device matches the previously registered key. Counter: title: Counter $ref: '#/components/schemas/Integer' description: Sequential counter used for cloning detection. Present only for U2F authentication. RetriesLeft: title: RetriesLeft - $ref: '#/components/schemas/Integer' + $ref: '#/components/schemas/Integer' description: RetriesLeft is the number of retries left before the financial transaction is rejected. It must be expressed in the form of the data type Integer. retriesLeft=1 means that this is the last retry before the financial transaction is rejected. Integer: title: Integer @@ -948,7 +1017,7 @@ components: pattern does not allow any trailing zeroes at all, but allows an amount without a minor currency unit. It also only allows four digits in the minor currency unit; a negative value is not allowed. Using more than 18 - digits in the major currency unit is not allowed. + digits in the major currency unit is not allowed. Currency: title: CurrencyEnum description: >- @@ -1206,7 +1275,7 @@ components: type: string minLength: 1 maxLength: 128 - description: Extension value. + description: Extension value. Extension: title: Extension type: object @@ -1220,7 +1289,7 @@ components: description: Extension value. required: - key - - value + - value ExtensionList: title: ExtensionList type: object @@ -1279,7 +1348,7 @@ components: - transferAmount - expiration - ilpPacket - - condition + - condition AuthorizationsPostRequest: title: AuthorizationsPostRequest type: object @@ -1296,10 +1365,10 @@ components: description: This is the transaction amount that will be withdrawn from the Payer’s account. transactionId: $ref: '#/components/schemas/CorrelationId' - description: Common ID (decided by the Payer FSP) between the FSPs for the future transaction object. The actual transaction will be created as part of a successful transfer process. + description: Common ID (decided by the Payer FSP) between the FSPs for the future transaction object. The actual transaction will be created as part of a successful transfer process. transactionRequestId: $ref: '#/components/schemas/CorrelationId' - description: The transactionRequestID, received from the POST /transactionRequests service earlier in the process. + description: The transactionRequestID, received from the POST /transactionRequests service earlier in the process. quote: $ref: '#/components/schemas/QuotesIDPutResponse' description: Quotes object @@ -1309,7 +1378,7 @@ components: - amount - transactionId - transactionRequestId - - quote + - quote transferStatus: type: string @@ -1317,7 +1386,7 @@ components: - ERROR_OCCURED - WAITING_FOR_QUOTE_ACCEPTANCE - COMPLETED - + idType: type: string enum: @@ -1330,21 +1399,21 @@ components: - ACCOUNT_ID - IBAN - ALIAS - + idValue: type: string minLength: 1 maxLength: 128 - + subIdValue: type: string minLength: 1 maxLength: 128 - + money: pattern: ^([0]|([1-9][0-9]{0,17}))([.][0-9]{0,3}[1-9])?$ type: string - + transferResponse: type: object required: @@ -1353,32 +1422,32 @@ components: homeTransactionId: type: string description: Transaction ID from the DFSP backend, used to reconcile transactions between the switch and DFSP backend systems - + currency: maxLength: 3 minLength: 3 type: string - + transferId: pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ type: string description: A Mojaloop API transfer identifier (UUID) - + quoteId: pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ type: string description: A Mojaloop API quote identifier (UUID) - + transactionRequestId: pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ type: string description: A Mojaloop API transaction request identifier (UUID) - + transactionId: pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ type: string description: ID of the transaction, the ID is decided by the Payer FSP during the creation of the quote - + transferParty: type: object required: @@ -1412,7 +1481,7 @@ components: merchantClassificationCode: type: string description: Up to 4 digits specifying the senders merchant classification, if known and applicable - + bulkQuoteRequest: type: object description: A request for a bulk quote @@ -1460,7 +1529,7 @@ components: $ref: '#/components/schemas/IndividualQuoteResult' description: Fees for each individual transaction, if any of them are charged per transaction. - + IndividualQuote: type: object description: Data model for individual quote in a bulk quote request @@ -1510,7 +1579,7 @@ components: minLength: 1 maxLength: 128 description: An optional note associated with the quote - + IndividualQuoteResult: type: object description: Data model for individual quote in a bulk quote response @@ -1524,7 +1593,7 @@ components: transferAmountCurrency: $ref: '#/components/schemas/currency' description: The currency of the transferAmount - payeeReceiveAmount: + payeeReceiveAmount: $ref: '#/components/schemas/money' description: The amount that the Payee should receive in the end-to-end transaction. Optional as the Payee FSP might not want to disclose any optional Payee fees payeeReceiveAmountCurrency: @@ -1534,20 +1603,20 @@ components: $ref: '#/components/schemas/money' description: Payee FSP’s part of the transaction fee payeeFspFeeAmountCurrency: - $ref: '#/components/schemas/currency' + $ref: '#/components/schemas/currency' description: The currency of the payeeFspFeeAmount payeeFspCommissionAmount: $ref: '#/components/schemas/money' description: Transaction commission from the Payee FSP payeeFspCommissionAmountCurrency: - $ref: '#/components/schemas/currency' + $ref: '#/components/schemas/currency' description: Currency of the payeeFspCommissionAmount - + bulkQuoteId: pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ type: string description: A Mojaloop API bulk quote identifier (UUID) - + bulkTransferRequest: type: object required: @@ -1566,7 +1635,7 @@ components: maxItems: 1000 items: $ref: '#/components/schemas/IndividualTransfer' - + IndividualTransfer: type: object description: Data model for individual transfer in a bulk transfer request @@ -1607,7 +1676,7 @@ components: minLength: 1 maxLength: 128 description: An optional note associated with the quote - + bulkTransferResponse: type: object required: @@ -1631,7 +1700,7 @@ components: pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ type: string description: A Mojaloop API transfer identifier (UUID) - + geoCode: type: object description: Indicates the geographic location from where the transaction was initiated. @@ -1643,17 +1712,17 @@ components: required: - latitude - longitude - + latitude: type: string pattern: ^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ description: The API data type Latitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. - + longitude: type: string pattern: ^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$ description: The API data type Longitude is a JSON String in a lexical format that is restricted by a regular expression for interoperability reasons. - + errorResponse: type: object properties: @@ -1663,7 +1732,7 @@ components: message: type: string description: Error message text - + extensionList: type: array items: @@ -1793,4 +1862,66 @@ components: required: - accountNickname - id - - currency \ No newline at end of file + - currency + + AccountAddress: + title: AccountAddress + type: string + description: | + A long-lived unique account identifier provided by the DFSP. This MUST NOT + be Bank Account Number or anything that may expose a User's private bank + account information. + pattern: '^([0-9A-Za-z_~\-\.]+[0-9A-Za-z_~\-])$' + minLength: 1 + maxLength: 1023 + + ConsentScopeType: + title: ConsentScopeType + type: string + enum: + - accounts.getBalance + - accounts.transfer + description: | + The scopes requested for a ConsentRequest. + - "accounts.getBalance" - Get the balance of a given account. + - "accounts.transfer" - Initiate a transfer from an account. + + Scope: + title: Scope + type: object + example: | + { + accountId: "dfsp.username.5678", + actions: [ "accounts.transfer", "accounts.getBalance" ] + } + properties: + accountId: + $ref: '#/components/schemas/AccountAddress' + actions: + type: array + items: + $ref: '#/components/schemas/ConsentScopeType' + required: + - accountId + - actions + + + ValidateOTPResponse: + title: ValidateOTPResponse + type: object + description: | + `POST /validateOTP` response. + properties: + isValid: + type: boolean + + ScopesIdResponse: + title: ScopesIdResponse + type: object + description: | + `GET /scopes/{ID}` response. + properties: + scopes: + type: array + items: + $ref: '#/components/schemas/Scope' diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index c1fbca7e..b7cd182f 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -230,6 +230,42 @@ const getAccountsByUserId = async (ctx) => { } }; +const getScopesById = async (ctx) => { + // fake scopes for testing purposes until consents storage is + // more fleshed out + const res = { + scopes: [ + { + "accountId": "dfsp.blue.account.one", + "actions": [ + "accounts.getBalance", + "accounts.transfer" + ] + }, + { + "accountId": "dfsp.blue.account.two", + "actions": [ + "accounts.getBalance", + "accounts.transfer" + ] + }, + ] + } + ctx.response.body = res; + ctx.response.status = 200; +}; + +const postValidateOTP = async (ctx) => { + // fake validation for testing purposes + // even auth tokens validate true + const res = { + isValid: ctx.request.body.authToken % 2 == 0 + } + ctx.state.logger.log(`postValidateOTP is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; +}; + const map = { '/': { get: healthCheck, @@ -279,6 +315,12 @@ const map = { '/accounts/{ID}': { get: getAccountsByUserId, }, + '/scopes/{ID}': { + get: getScopesById, + }, + '/validateOTP': { + post: postValidateOTP, + } }; diff --git a/src/test/simulator.js b/src/test/simulator.js index 4495f64d..084e6911 100644 --- a/src/test/simulator.js +++ b/src/test/simulator.js @@ -65,6 +65,43 @@ test('get accounts by user Id', async (t) => { t.is(t.context.response.status, 404); }); +test('get scopes by Id', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { ID: 'test123' } }; + await map['/scopes/{ID}'].get(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 200); +}); + +test('post validate otp valid', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { + body: { + authToken: '123456', + consentRequestId: idValue + } + }; + await map['/validateOTP'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.body.isValid, true); + t.is(t.context.response.status, 200); +}); + + +test('post validate otp invalid', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { + body: { + authToken: '123457', + consentRequestId: idValue + } + }; + await map['/validateOTP'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.body.isValid, false); + t.is(t.context.response.status, 200); +}); + test('get a party', async (t) => { await t.context.state.model.party.create(party); // eslint-disable-next-line no-param-reassign From 946f458effa7bf2fde67743d2e1be61a7414c5a8 Mon Sep 17 00:00:00 2001 From: sridharvoruganti <36686863+sridharvoruganti@users.noreply.github.com> Date: Mon, 12 Apr 2021 21:37:42 +0530 Subject: [PATCH 13/34] feat: add consentRequests related endpoints (#94) * feat: add consentRequests related endpoints * chore: improve test coverage --- src/audit-resolve.json | 24 +- src/lib/objectStore/inMemoryImpl.js | 41 +++ src/lib/objectStore/objectStoreInterface.js | 44 +++ src/simulator/api.yaml | 255 +++++++++++++++++- src/simulator/handlers.js | 95 +++++-- src/test/simulator.js | 51 +++- src/test/unit/objectStore/objectStore.test.js | 37 +++ 7 files changed, 512 insertions(+), 35 deletions(-) create mode 100644 src/lib/objectStore/inMemoryImpl.js create mode 100644 src/lib/objectStore/objectStoreInterface.js create mode 100644 src/test/unit/objectStore/objectStore.test.js diff --git a/src/audit-resolve.json b/src/audit-resolve.json index cea3d051..149476fb 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -7,33 +7,33 @@ }, "1589|sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1615383991700, - "expiresAt": 1617975978786 + "madeAt": 1617995554900, + "expiresAt": 1618600328607 }, "1589|00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1615383991701, - "expiresAt": 1617975978786 + "madeAt": 1617995554900, + "expiresAt": 1618600328607 }, "1589|00unidentified>00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1615383991701, - "expiresAt": 1617975978786 + "madeAt": 1617995554900, + "expiresAt": 1618600328607 }, "1589|ava>update-notifier>latest-version>package-json>registry-auth-token>rc>ini": { "decision": "ignore", - "madeAt": 1615383991701, - "expiresAt": 1617975978786 + "madeAt": 1617995554900, + "expiresAt": 1618600328607 }, "1589|ava>update-notifier>latest-version>package-json>registry-url>rc>ini": { "decision": "ignore", - "madeAt": 1615383991701, - "expiresAt": 1617975978786 + "madeAt": 1617995554900, + "expiresAt": 1618600328607 }, "1589|ava>update-notifier>is-installed-globally>global-dirs>ini": { "decision": "ignore", - "madeAt": 1615383991701, - "expiresAt": 1617975978786 + "madeAt": 1617995554900, + "expiresAt": 1618600328607 }, "1654|ava>yargs>y18n": { "decision": "fix", diff --git a/src/lib/objectStore/inMemoryImpl.js b/src/lib/objectStore/inMemoryImpl.js new file mode 100644 index 00000000..e64e3b7c --- /dev/null +++ b/src/lib/objectStore/inMemoryImpl.js @@ -0,0 +1,41 @@ + +/***** + 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 + + * ModusBox + * Vijaya Kumar Guthi (Original Author) + -------------- + ******/ + +const storedObject = { +}; + +const set = async (key, value) => { + storedObject[key] = { ...value }; +}; + +const get = async (key) => ({ ...storedObject[key] }); + +const init = async () => null; + +module.exports = { + set, + get, + init, +}; diff --git a/src/lib/objectStore/objectStoreInterface.js b/src/lib/objectStore/objectStoreInterface.js new file mode 100644 index 00000000..f59fa5b1 --- /dev/null +++ b/src/lib/objectStore/objectStoreInterface.js @@ -0,0 +1,44 @@ +/***** + 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 + + * ModusBox + * Vijaya Kumar Guthi (Original Author) + -------------- + ******/ + +const objectStoreImpl = require('./inMemoryImpl'); + +const set = async (key, value) => { + await objectStoreImpl.set(key, value); +}; + +const get = async (key) => { + const value = await objectStoreImpl.get(key); + return value; +}; + +const init = async () => { + await objectStoreImpl.init(); +}; + +module.exports = { + set, + get, + init, +}; diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index ce8f88fc..ffcd5d29 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -651,6 +651,154 @@ paths: application/json: schema: $ref: '#/components/schemas/errorResponse' + + /validateConsentRequests: + post: + operationId: PostValidateConsentRequests + summary: PostValidateConsentRequests + description: | + The HTTP request `POST /validateConsentRequests` is used to validate ConsentRequests + tags: + - ConsentRequests + requestBody: + description: An incoming consentRequest + content: + application/json: + schema: + $ref: '#/components/schemas/ConsentRequestsPostRequest' + responses: + 200: + description: Response containing validation details + content: + application/json: + schema: + $ref: '#/components/schemas/ConsentRequestsPostResponse' + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + /sendOTP: + post: + tags: + - DFSPSim + description: The HTTP request `POST /sendOTP` is used to send OTP to a DFSP user (most likely through SMS). + summary: SendOTP + operationId: SendOTP + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SendOTPRequest' + example: + userName: dfspa.user.name + consentRequestId: 3b346cec-47b3-4def-b870-edb255aaf6c3 + message: '9876' + responses: + 200: + description: Response containing validation details + content: + application/json: + schema: + $ref: '#/components/schemas/SendOTPResponse' + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + + /store/consentRequests/{ID}: + get: + tags: + - DFSPSim + operationId: GetConsentRequest + summary: GetConsentRequest + description: | + The HTTP request `GET /store/consentRequests/{ID}` is used by DFSP to load a specified consentRequest. + responses: + 200: + description: Response containing consentRequest details + content: + application/json: + schema: + $ref: '#/components/schemas/ScopesIdResponse' + example: + scopes: + - accountId: dfspa.username.1234 + actions: + - accounts.transfer + - accounts.getBalance + - accountId: dfspa.username.5678 + actions: + - accounts.transfer + - accounts.getBalance + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + post: + tags: + - DFSPSim + operationId: StoreConsentRequest + summary: StoreConsentRequest + description: | + The HTTP request `POST /store/consentRequests/{ID}` is used by a DFSP to store consentRequests. + requestBody: + description: The consentRequest to store + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ScopesIdResponse' + example: + scopes: + - accountId: dfspa.username.1234 + actions: + - accounts.transfer + - accounts.getBalance + - accountId: dfspa.username.5678 + actions: + - accounts.transfer + - accounts.getBalance + responses: + 200: + description: OK + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + components: schemas: @@ -1776,6 +1924,17 @@ components: - COMMITTED DFSP has successfully performed the transfer. - ABORTED DFSP has aborted the transfer due a rejection or failure to perform the transfer. + ConsentRequestChannelType: + title: ConsentRequestChannelType + type: string + enum: + - WEB + - OTP + description: | + The auth channel being used for the consentRequest. + - "WEB" - The Web auth channel. + - "OTP" - The OTP auth channel. + fulfilNotification: title: TransfersIDPatchResponse type: object @@ -1832,6 +1991,38 @@ components: - authenticationInfo - transactionRequestId + ConsentRequestsPostRequest: + title: ConsentRequestsPostRequest + type: object + description: The object sent in a `POST /consentRequests` request. + properties: + id: + $ref: '#/components/schemas/CorrelationId' + initiatorId: + type: string + description: >- + The id of the PISP who will initiate transactions on a user's + behalf. + scopes: + type: array + items: + $ref: '#/components/schemas/Scope' + authChannels: + type: array + items: + $ref: '#/components/schemas/ConsentRequestChannelType' + callbackUri: + type: string + description: >- + The callback uri that the user will be redirected to after + completing the WEB auth channel. + required: + - id + - initiatorId + - scopes + - authChannels + - callbackUri + AuthorizationResponse: title: AuthorizationResponse type: string @@ -1905,7 +2096,6 @@ components: - accountId - actions - ValidateOTPResponse: title: ValidateOTPResponse type: object @@ -1925,3 +2115,66 @@ components: type: array items: $ref: '#/components/schemas/Scope' + + ConsentRequestsPostResponse: + title: ConsentRequestsPostResponse + type: object + description: | + `POST /validateConsentRequests` response. + properties: + isValid: + type: boolean + authChannels: + type: array + items: + $ref: '#/components/schemas/ConsentRequestChannelType' + authUri: + type: string + description: >- + The callback uri that the pisp app redirects to for user to complete + their login. + UserName: + title: UserName + type: string + minLength: 1 + maxLength: 25 + Password: + title: Password + type: string + minLength: 1 + maxLength: 25 + Message: + title: Message + type: string + description: OTP value or error message + + SendOTPRequest: + title: SendOTPRequest + type: object + description: 'POST /sendOTP request' + properties: + userName: + $ref: '#/components/schemas/UserName' + consentRequestId: + $ref: '#/components/schemas/CorrelationId' + message: + $ref: '#/components/schemas/Message' + required: + - consentRequestId + SendOTPResponse: + title: SendOTPResponse + type: object + description: | + `POST /sendOTP` response. + properties: + otp: + type: string + StoreConsentRequest: + title: StoreConsentRequest + type: object + description: 'store consent request details' + properties: + scopes: + $ref: '#/components/schemas/ScopesIdResponse' + required: + - scopes \ No newline at end of file diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index b7cd182f..e0015a22 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -30,7 +30,7 @@ const crypto = require('crypto'); require('dotenv').config(); const { getStackOrInspect } = require('@internal/log'); const { ApiErrorCodes } = require('../models/errors.js'); - +const objectStore = require('../lib/objectStore/objectStoreInterface'); const getParticipantsByTypeAndId = async (ctx) => { try { @@ -124,7 +124,6 @@ const putTransfersById = async (ctx) => { } }; - const postQuotes = async (ctx) => { try { const res = await ctx.state.model.quote.create(ctx.request.body); @@ -236,21 +235,21 @@ const getScopesById = async (ctx) => { const res = { scopes: [ { - "accountId": "dfsp.blue.account.one", - "actions": [ - "accounts.getBalance", - "accounts.transfer" - ] + accountId: 'dfsp.blue.account.one', + actions: [ + 'accounts.getBalance', + 'accounts.transfer', + ], }, { - "accountId": "dfsp.blue.account.two", - "actions": [ - "accounts.getBalance", - "accounts.transfer" - ] + accountId: 'dfsp.blue.account.two', + actions: [ + 'accounts.getBalance', + 'accounts.transfer', + ], }, - ] - } + ], + }; ctx.response.body = res; ctx.response.status = 200; }; @@ -259,13 +258,64 @@ const postValidateOTP = async (ctx) => { // fake validation for testing purposes // even auth tokens validate true const res = { - isValid: ctx.request.body.authToken % 2 == 0 - } + isValid: ctx.request.body.authToken % 2 === 0, + }; ctx.state.logger.log(`postValidateOTP is returning body: ${util.inspect(res)}`); ctx.response.body = res; ctx.response.status = 200; }; +const validateConsentRequests = async (ctx) => { + const request = ctx.request.body; + ctx.state.logger.log(`validateConsentRequests request body: ${util.inspect(request)}`); + // default mock reponse, if rules not configured + const res = { + isValid: true, + authChannels: ['WEB'], + authUri: `dfspa.com/authorize?consentRequestId=${request.id}`, + }; + ctx.state.logger.log(`validateConsentRequests is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; +}; + +const sendOTP = async (ctx) => { + const request = ctx.request.body; + ctx.state.logger.log(`sendOTP request body: ${util.inspect(request)}`); + // default mock reponse, if rules not configured + const res = { + otp: Math.floor(Math.random() * 90000) + 10000, + }; + await objectStore.set(`${request.consentRequestId}-OTP`, res); + ctx.state.logger.log(`sendOTP is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; +}; + +const storeConsentRequest = async (ctx) => { + const { ID } = ctx.state.path.params; + const request = ctx.request.body; + ctx.state.logger.log(`storeConsentRequest request body: ${util.inspect(request)}`); + // default mock reponse, if rules not configured + const res = { + status: 'OK', + }; + await objectStore.set(`${ID}-CR`, request); + ctx.state.logger.log(`sendOTP is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; +}; + +const getConsentRequest = async (ctx) => { + const { ID } = ctx.state.path.params; + ctx.state.logger.log(`getConsentRequest : ${ID}`); + // default mock reponse, if rules not configured + const res = await objectStore.get(`${ID}-CR`); + ctx.state.logger.log(`getConsentRequest is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; +}; + const map = { '/': { get: healthCheck, @@ -320,10 +370,19 @@ const map = { }, '/validateOTP': { post: postValidateOTP, - } + }, + '/validateConsentRequests': { + post: validateConsentRequests, + }, + '/sendOTP': { + post: sendOTP, + }, + '/store/consentRequests/{ID}': { + get: getConsentRequest, + post: storeConsentRequest, + }, }; - module.exports = { map, }; diff --git a/src/test/simulator.js b/src/test/simulator.js index 084e6911..860ff887 100644 --- a/src/test/simulator.js +++ b/src/test/simulator.js @@ -73,13 +73,56 @@ test('get scopes by Id', async (t) => { t.is(t.context.response.status, 200); }); +test('post validateConsentRequests', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { + body: { id: '123456' }, + }; + await map['/validateConsentRequests'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.body.isValid, true); + t.is(t.context.response.status, 200); +}); + +test('post sendOTP', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.request = { + body: { consentRequestId: '123456' }, + }; + await map['/sendOTP'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 200); +}); + +test('post storeConsentRequest', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { ID: '123456' } }; + // eslint-disable-next-line no-param-reassign + t.context.request = { + body: { consentRequestId: '123456' }, + }; + await map['/store/consentRequests/{ID}'].post(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.body.status, 'OK'); + t.is(t.context.response.status, 200); +}); + +test('get consentRequest', async (t) => { + // eslint-disable-next-line no-param-reassign + t.context.state.path = { params: { ID: '123456' } }; + + await map['/store/consentRequests/{ID}'].get(t.context); + t.truthy(t.context.response.body); + t.is(t.context.response.status, 200); +}); + test('post validate otp valid', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { body: { authToken: '123456', - consentRequestId: idValue - } + consentRequestId: idValue, + }, }; await map['/validateOTP'].post(t.context); t.truthy(t.context.response.body); @@ -93,8 +136,8 @@ test('post validate otp invalid', async (t) => { t.context.request = { body: { authToken: '123457', - consentRequestId: idValue - } + consentRequestId: idValue, + }, }; await map['/validateOTP'].post(t.context); t.truthy(t.context.response.body); diff --git a/src/test/unit/objectStore/objectStore.test.js b/src/test/unit/objectStore/objectStore.test.js new file mode 100644 index 00000000..4b93a5d4 --- /dev/null +++ b/src/test/unit/objectStore/objectStore.test.js @@ -0,0 +1,37 @@ +/***** + 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 + + - Sridhar Voruganti - sridhar.voruganti@modusbox.com + -------------- + ******/ +'use strict'; + +const test = require('ava'); +const objectStore = require('../../../lib/objectStore/objectStoreInterface'); + +test('test store and get', async (t) => { + const testObj = { + testKey: 'test=value', + }; + await objectStore.init(); + await objectStore.set('test', testObj); + const storedValue = await objectStore.get('test'); + t.deepEqual(storedValue, testObj, 'Response did not match expected'); +}); From b1929d663ebb691d56c9bd42795c95f4122c094a Mon Sep 17 00:00:00 2001 From: sridharvoruganti <36686863+sridharvoruganti@users.noreply.github.com> Date: Thu, 15 Apr 2021 15:45:55 +0530 Subject: [PATCH 14/34] chore: update consentRequests response structure (#95) * chore: update consentRequests response structure * chore: fix linting issue --- src/simulator/api.yaml | 31 +++++++++++++++++++++---------- src/simulator/handlers.js | 6 ++++-- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index ffcd5d29..d596f3ea 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -2124,15 +2124,20 @@ components: properties: isValid: type: boolean - authChannels: - type: array - items: - $ref: '#/components/schemas/ConsentRequestChannelType' - authUri: - type: string - description: >- - The callback uri that the pisp app redirects to for user to complete - their login. + data: + type: object + properties: + authChannels: + type: array + items: + $ref: '#/components/schemas/ConsentRequestChannelType' + authUri: + type: string + description: >- + The callback uri that the pisp app redirects to for user to complete + their login. + errorInformation: + $ref: '#/components/schemas/ErrorInformation' UserName: title: UserName type: string @@ -2147,7 +2152,13 @@ components: title: Message type: string description: OTP value or error message - + ErrorInformation: + type: object + properties: + errorCode: + type: string + errorDescription: + type: string SendOTPRequest: title: SendOTPRequest type: object diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index e0015a22..191f19b4 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -271,8 +271,10 @@ const validateConsentRequests = async (ctx) => { // default mock reponse, if rules not configured const res = { isValid: true, - authChannels: ['WEB'], - authUri: `dfspa.com/authorize?consentRequestId=${request.id}`, + data: { + authChannels: ['WEB'], + authUri: `dfspa.com/authorize?consentRequestId=${request.id}`, + }, }; ctx.state.logger.log(`validateConsentRequests is returning body: ${util.inspect(res)}`); ctx.response.body = res; From 2c815be9a232bd7bbbc0636a3cd24ed044c5b6e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marzec?= <2881004+eoln@users.noreply.github.com> Date: Mon, 10 May 2021 12:54:44 +0200 Subject: [PATCH 15/34] feat: 2108 validate thirdparty transaction request (#97) * feat(dfspTransactions): verify thridparty request transaction and proper scheme for verify authorization * postpone vulnerabilites * fix api.yaml * fix api.yaml --- src/audit-resolve.json | 314 ++++++++++++++++++++++- src/simulator/api.yaml | 566 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 866 insertions(+), 14 deletions(-) diff --git a/src/audit-resolve.json b/src/audit-resolve.json index 149476fb..3b07a41a 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -7,33 +7,33 @@ }, "1589|sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1617995554900, - "expiresAt": 1618600328607 + "madeAt": 1620638321689, + "expiresAt": 1623230315330 }, "1589|00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1617995554900, - "expiresAt": 1618600328607 + "madeAt": 1620638321689, + "expiresAt": 1623230315330 }, "1589|00unidentified>00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { "decision": "ignore", - "madeAt": 1617995554900, - "expiresAt": 1618600328607 + "madeAt": 1620638321689, + "expiresAt": 1623230315330 }, "1589|ava>update-notifier>latest-version>package-json>registry-auth-token>rc>ini": { "decision": "ignore", - "madeAt": 1617995554900, - "expiresAt": 1618600328607 + "madeAt": 1620638321689, + "expiresAt": 1623230315330 }, "1589|ava>update-notifier>latest-version>package-json>registry-url>rc>ini": { "decision": "ignore", - "madeAt": 1617995554900, - "expiresAt": 1618600328607 + "madeAt": 1620638321689, + "expiresAt": 1623230315330 }, "1589|ava>update-notifier>is-installed-globally>global-dirs>ini": { "decision": "ignore", - "madeAt": 1617995554900, - "expiresAt": 1618600328607 + "madeAt": 1620638321689, + "expiresAt": 1623230315330 }, "1654|ava>yargs>y18n": { "decision": "fix", @@ -46,6 +46,296 @@ "1654|npm-audit-resolver>yargs-unparser>yargs>y18n": { "decision": "fix", "madeAt": 1617075431111 + }, + "1673|ava>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|eslint>inquirer>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|eslint>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|eslint>table>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|npm-audit-resolver>yargs-unparser>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-optimise-call-expression>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/template>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-split-export-declaration>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/types>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/traverse>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|nyc>istanbul-lib-instrument>@babel/core>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1673|tap-xunit>xmlbuilder>lodash": { + "decision": "ignore", + "madeAt": 1620638324097, + "expiresAt": 1623230315330 + }, + "1677|ava>read-pkg>normalize-package-data>hosted-git-info": { + "decision": "ignore", + "madeAt": 1620638325847, + "expiresAt": 1623230315330 + }, + "1677|eslint-plugin-import>read-pkg-up>read-pkg>normalize-package-data>hosted-git-info": { + "decision": "ignore", + "madeAt": 1620638325847, + "expiresAt": 1623230315330 } }, "rules": {}, diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index d596f3ea..08f95711 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -528,7 +528,7 @@ paths: content: application/json: schema: - type: object + $ref: '#/components/schemas/AuthorizationsIDPutResponse' responses: 200: description: 'post accepted' @@ -536,6 +536,11 @@ paths: application/json: schema: type: object + properties: + isValid: + type: boolean + required: + - isValid 400: description: 'invalid request' content: @@ -799,6 +804,40 @@ paths: schema: $ref: '#/components/schemas/errorResponse' + /validate-thirdparty-transaction-request: + post: + operationId: PostValidateThirdpartyTransactionRequest + summary: PostValidateThirdpartyTransactionRequest + description: | + The HTTP request `POST /validate-thirdparty-transaction-request` is used to validate ThirdpartyRequestTransaction + tags: + - ThirdpartyRequestTransaction + requestBody: + description: An incoming ThirdpartyTransactionRequest + content: + application/json: + schema: + $ref: '#/components/schemas/ThirdpartyRequestsTransactionsPostRequest' + responses: + 200: + description: Response containing validation details + content: + application/json: + schema: + $ref: '#/components/schemas/ValidateThirdpartyRequestsTransactionsPostResponse' + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + components: schemas: @@ -2138,6 +2177,16 @@ components: their login. errorInformation: $ref: '#/components/schemas/ErrorInformation' + ValidateThirdpartyRequestsTransactionsPostResponse: + title: ValidateThirdpartyRequestsTransactionsPostResponse + type: object + description: | + `POST /validate-thirdparty-transaction-request` response. + properties: + isValid: + type: boolean + required: + - isValid UserName: title: UserName type: string @@ -2188,4 +2237,517 @@ components: scopes: $ref: '#/components/schemas/ScopesIdResponse' required: - - scopes \ No newline at end of file + - scopes + TransactionScenario: + title: TransactionScenario + type: string + enum: + - DEPOSIT + - WITHDRAWAL + - TRANSFER + - PAYMENT + - REFUND + description: >- + Below are the allowed values for the enumeration. + + - DEPOSIT - Used for performing a Cash-In (deposit) transaction. In a + normal scenario, electronic funds are transferred from a Business + account to a Consumer account, and physical cash is given from the + Consumer to the Business User. + + - WITHDRAWAL - Used for performing a Cash-Out (withdrawal) transaction. + In a normal scenario, electronic funds are transferred from a Consumer’s + account to a Business account, and physical cash is given from the + Business User to the Consumer. + + - TRANSFER - Used for performing a P2P (Peer to Peer, or Consumer to + Consumer) transaction. + + - PAYMENT - Usually used for performing a transaction from a Consumer to + a Merchant or Organization, but could also be for a B2B (Business to + Business) payment. The transaction could be online for a purchase in an + Internet store, in a physical store where both the Consumer and Business + User are present, a bill payment, a donation, and so on. + + - REFUND - Used for performing a refund of transaction. + example: DEPOSIT + TransactionSubScenario: + title: TransactionSubScenario + type: string + pattern: '^[A-Z_]{1,32}$' + description: >- + Possible sub-scenario, defined locally within the scheme (UndefinedEnum + Type). + example: LOCALLY_DEFINED_SUBSCENARIO + TransactionInitiator: + title: TransactionInitiator + type: string + enum: + - PAYER + - PAYEE + description: >- + Below are the allowed values for the enumeration. + + - PAYER - Sender of funds is initiating the transaction. The account to + send from is either owned by the Payer or is connected to the Payer in + some way. + + - PAYEE - Recipient of the funds is initiating the transaction by + sending a transaction request. The Payer must approve the transaction, + either automatically by a pre-generated OTP or by pre-approval of the + Payee, or by manually approving in his or her own Device. + example: PAYEE + TransactionInitiatorType: + title: TransactionInitiatorType + type: string + enum: + - CONSUMER + - AGENT + - BUSINESS + - DEVICE + description: |- + Below are the allowed values for the enumeration. + - CONSUMER - Consumer is the initiator of the transaction. + - AGENT - Agent is the initiator of the transaction. + - BUSINESS - Business is the initiator of the transaction. + - DEVICE - Device is the initiator of the transaction. + example: CONSUMER + RefundReason: + title: RefundReason + type: string + minLength: 1 + maxLength: 128 + description: Reason for the refund. + example: Free text indicating reason for the refund. + Refund: + title: Refund + type: object + description: Data model for the complex type Refund. + properties: + originalTransactionId: + $ref: '#/components/schemas/CorrelationId' + refundReason: + $ref: '#/components/schemas/RefundReason' + required: + - originalTransactionId + BalanceOfPayments: + title: BalanceOfPayments + type: string + pattern: '^[1-9]\d{2}$' + description: >- + (BopCode) The API data type + [BopCode](https://www.imf.org/external/np/sta/bopcode/) is a JSON String + of 3 characters, consisting of digits only. Negative numbers are not + allowed. A leading zero is not allowed. + example: '123' + TransactionType: + title: TransactionType + type: object + description: Data model for the complex type TransactionType. + properties: + scenario: + $ref: '#/components/schemas/TransactionScenario' + subScenario: + $ref: '#/components/schemas/TransactionSubScenario' + initiator: + $ref: '#/components/schemas/TransactionInitiator' + initiatorType: + $ref: '#/components/schemas/TransactionInitiatorType' + refundInfo: + $ref: '#/components/schemas/Refund' + balanceOfPayments: + $ref: '#/components/schemas/BalanceOfPayments' + required: + - scenario + - initiator + - initiatorType + PartyName: + title: PartyName + type: string + minLength: 1 + maxLength: 128 + description: Name of the Party. Could be a real name or a nickname. + FirstName: + title: FirstName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: First name of the Party (Name Type). + example: Henrik + MiddleName: + title: MiddleName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: Middle name of the Party (Name Type). + example: Johannes + LastName: + title: LastName + type: string + minLength: 1 + maxLength: 128 + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: Last name of the Party (Name Type). + example: Karlsson + PartyComplexName: + title: PartyComplexName + type: object + description: Data model for the complex type PartyComplexName. + properties: + firstName: + $ref: '#/components/schemas/FirstName' + middleName: + $ref: '#/components/schemas/MiddleName' + lastName: + $ref: '#/components/schemas/LastName' + DateOfBirth: + title: DateofBirth (type Date) + type: string + pattern: >- + ^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)$ + description: Date of Birth of the Party. + example: '1966-06-16' + PartyPersonalInfo: + title: PartyPersonalInfo + type: object + description: Data model for the complex type PartyPersonalInfo. + properties: + complexName: + $ref: '#/components/schemas/PartyComplexName' + dateOfBirth: + $ref: '#/components/schemas/DateOfBirth' + Party: + title: Party + type: object + description: Data model for the complex type Party. + properties: + accounts: + $ref: '#/components/schemas/AccountList' + partyIdInfo: + $ref: '#/components/schemas/PartyIdInfo' + merchantClassificationCode: + $ref: '#/components/schemas/MerchantClassificationCode' + name: + $ref: '#/components/schemas/PartyName' + personalInfo: + $ref: '#/components/schemas/PartyPersonalInfo' + required: + - partyIdInfo + PartyIdTypeTPLink: + title: PartyIdTypeTPLink + type: string + enum: + - THIRD_PARTY_LINK + description: > + This is a variant based on FSPIOP `PartyIdType` specification. + + This validation interface should be use by `POST + /thirdpartyRequests/transactions` + + - THIRD_PARTY_LINK - is the DFSP's internal reference which allows DFSP + to find out the corresponding consent + example: PERSONAL_ID + PartyIdInfoTPLink: + title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + $ref: '#/components/schemas/PartyIdTypeTPLink' + partyIdentifier: + $ref: '#/components/schemas/PartyIdentifier' + partySubIdOrType: + $ref: '#/components/schemas/PartySubIdOrType' + fspId: + $ref: '#/components/schemas/FspId' + extensionList: + $ref: '#/components/schemas/ExtensionList' + required: + - partyIdType + - partyIdentifier + PartyIdType: + title: PartyIdType + type: string + enum: + - MSISDN + - EMAIL + - PERSONAL_ID + - BUSINESS + - DEVICE + - ACCOUNT_ID + - IBAN + - ALIAS + - CONSENT + - THIRD_PARTY_LINK + description: > + This is a variant based on FSPIOP `PartyIdType` specification. + + Main difference being the CONSENT and THIRD_PARTY_LINK enums. + + + Below are the allowed values for the enumeration. + + - MSISDN - An MSISDN (Mobile Station International Subscriber Directory + + Number, that is, the phone number) is used as reference to a + participant. + + The MSISDN identifier should be in international format according to the + + [ITU-T E.164 standard](https://www.itu.int/rec/T-REC-E.164/en). + + Optionally, the MSISDN may be prefixed by a single plus sign, indicating + the + + international prefix. + + - EMAIL - An email is used as reference to a + + participant. The format of the email should be according to the + informational + + [RFC 3696](https://tools.ietf.org/html/rfc3696). + + - PERSONAL_ID - A personal identifier is used as reference to a + participant. + + Examples of personal identification are passport number, birth + certificate + + number, and national registration number. The identifier number is added + in + + the PartyIdentifier element. The personal identifier type is added in + the + + PartySubIdOrType element. + + - BUSINESS - A specific Business (for example, an organization or a + company) + + is used as reference to a participant. The BUSINESS identifier can be in + any + + format. To make a transaction connected to a specific username or bill + number + + in a Business, the PartySubIdOrType element should be used. + + - DEVICE - A specific device (for example, a POS or ATM) ID connected to + a + + specific business or organization is used as reference to a Party. + + For referencing a specific device under a specific business or + organization, + + use the PartySubIdOrType element. + + - ACCOUNT_ID - A bank account number or FSP account ID should be used as + + reference to a participant. The ACCOUNT_ID identifier can be in any + format, + + as formats can greatly differ depending on country and FSP. + + - IBAN - A bank account number or FSP account ID is used as reference to + a + + participant. The IBAN identifier can consist of up to 34 alphanumeric + + characters and should be entered without whitespace. + + - ALIAS An alias is used as reference to a participant. The alias should + be + + created in the FSP as an alternative reference to an account owner. + + Another example of an alias is a username in the FSP system. + + The ALIAS identifier can be in any format. It is also possible to use + the + + PartySubIdOrType element for identifying an account under an Alias + defined + + by the PartyIdentifier. + + - CONSENT - TBD + + - THIRD_PARTY_LINK - TBD + example: PERSONAL_ID + PartyIdentifier: + title: PartyIdentifier + type: string + minLength: 1 + maxLength: 128 + description: Identifier of the Party. + example: '16135551212' + PartySubIdOrType: + title: PartySubIdOrType + type: string + minLength: 1 + maxLength: 128 + description: >- + Either a sub-identifier of a PartyIdentifier, or a sub-type of the + PartyIdType, normally a PersonalIdentifierType. + FspId: + title: FspId + type: string + minLength: 1 + maxLength: 32 + description: FSP identifier. + PartyIdInfo: + title: PartyIdInfo + type: object + description: Data model for the complex type PartyIdInfo. + properties: + partyIdType: + $ref: '#/components/schemas/PartyIdType' + partyIdentifier: + $ref: '#/components/schemas/PartyIdentifier' + partySubIdOrType: + $ref: '#/components/schemas/PartySubIdOrType' + fspId: + $ref: '#/components/schemas/FspId' + extensionList: + $ref: '#/components/schemas/ExtensionList' + required: + - partyIdType + - partyIdentifier + MerchantClassificationCode: + title: MerchantClassificationCode + type: string + pattern: '^[\d]{1,4}$' + description: >- + A limited set of pre-defined numbers. This list would be a limited set + of numbers identifying a set of popular merchant types like School Fees, + Pubs and Restaurants, Groceries, etc. + AmountType: + title: AmountType + type: string + enum: + - SEND + - RECEIVE + description: >- + Below are the allowed values for the enumeration AmountType. + + - SEND - Amount the Payer would like to send, that is, the amount that + should be withdrawn from the Payer account including any fees. + + - RECEIVE - Amount the Payer would like the Payee to receive, that is, + the amount that should be sent to the receiver exclusive of any fees. + example: RECEIVE + ThirdpartyRequestsTransactionsPostRequest: + title: ThirdpartyRequestsTransactionsPostRequest + type: object + description: The object sent in the POST /thirdpartyRequests/transactions request. + properties: + transactionRequestId: + allOf: + - $ref: '#/components/schemas/CorrelationId' + description: > + Common ID between the FSPs for the transaction request object. The + ID should be reused for resends of the same transaction request. A + new ID should be generated for each new transaction request. + payee: + allOf: + - $ref: '#/components/schemas/Party' + description: Information about the Payee in the proposed financial transaction. + payer: + allOf: + - $ref: '#/components/schemas/PartyIdInfoTPLink' + description: Information about the Payer in the proposed financial transaction. + amountType: + allOf: + - $ref: '#/components/schemas/AmountType' + description: 'SEND for sendAmount, RECEIVE for receiveAmount.' + amount: + allOf: + - $ref: '#/components/schemas/Money' + description: Requested amount to be transferred from the Payer to Payee. + transactionType: + allOf: + - $ref: '#/components/schemas/TransactionType' + description: Type of transaction. + expiration: + type: string + description: > + Date and time until when the transaction request is valid. It can be + set to get a quick failure in case the peer FSP takes too long to + respond. + example: '2016-05-24T08:38:08.699-04:00' + required: + - transactionRequestId + - payee + - payer + - amountType + - amount + - transactionType + - expiration + Name: + title: Name + type: string + pattern: '^(?!\s*$)[\w .,''-]{1,128}$' + description: >- + The API data type Name is a JSON String, restricted by a regular + expression to avoid characters which are generally not used in a name. + + + Regular Expression - The regular expression for restricting the Name + type is "^(?!\s*$)[\w .,'-]{1,128}$". The restriction does not allow a + string consisting of whitespace only, all Unicode characters are + allowed, as well as the period (.) (apostrophe (‘), dash (-), comma (,) + and space characters ( ). + + + **Note:** In some programming languages, Unicode support must be + specifically enabled. For example, if Java is used, the flag + UNICODE_CHARACTER_CLASS must be enabled to allow Unicode characters. + Account: + title: Account + type: object + description: Data model for the complex type Account. + properties: + address: + $ref: '#/components/schemas/AccountAddress' + currency: + $ref: '#/components/schemas/Currency' + description: + $ref: '#/components/schemas/Name' + required: + - currency + AccountList: + title: AccountList + type: object + description: Data model for the complex type AccountList. + properties: + account: + type: array + items: + $ref: '#/components/schemas/Account' + minItems: 1 + maxItems: 32 + description: Accounts associated with the Party. + required: + - account + AuthorizationsIDPutResponse: + title: AuthorizationsIDPutResponse + type: object + description: 'The object sent in the PUT /authorizations/{ID} callback.' + properties: + authenticationInfo: + $ref: '#/components/schemas/AuthenticationInfo' + description: 'OTP or QR Code if entered, otherwise empty.' + example: OTP + responseType: + $ref: '#/components/schemas/AuthorizationResponse' + description: >- + Enum containing response information; if the customer entered the + authentication value, rejected the transaction, or requested a + resend of the authentication value. + example: ENTERED + required: + - responseType \ No newline at end of file From 2275c05fcc3bfb68db8655d846345d21c4b4d928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marzec?= Date: Mon, 10 May 2021 13:07:03 +0200 Subject: [PATCH 16/34] chore: update contrib list --- src/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index dc0d5b85..14ed1b7b 100644 --- a/src/package.json +++ b/src/package.json @@ -12,7 +12,8 @@ "Steven Oderayi ", "Valentin Genev ", "ModusBox", - "Mowali" + "Mowali", + "Paweł Marzec " ], "repository": { "type": "git", From a278d05f963072b2526520ff1e0c056d8af50f85 Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Tue, 18 May 2021 11:35:01 -0500 Subject: [PATCH 17/34] chore: update accounts interface (#103) --- src/simulator/api.yaml | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 08f95711..86b7e853 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -2077,22 +2077,28 @@ components: AccountsIDPutResponse: title: AccountsIDPutResponse - type: array - items: - type: object - description: | - `GET /accounts/{ID}` response. - properties: - accountNickname: - $ref: '#/components/schemas/accountAddress' - id: - $ref: '#/components/schemas/accountAddress' - currency: - $ref: '#/components/schemas/currency' - required: - - accountNickname - - id - - currency + type: object + description: 'The object sent in a `PUT /accounts/{ID}` request.' + properties: + accounts: + type: array + items: + type: object + description: | + The object sent in a `PUT /accounts/{ID}` request. + properties: + accountNickname: + $ref: '#/components/schemas/AccountAddress' + id: + $ref: '#/components/schemas/AccountAddress' + currency: + $ref: '#/components/schemas/Currency' + required: + - accountNickname + - id + - currency + required: + - accounts AccountAddress: title: AccountAddress @@ -2750,4 +2756,4 @@ components: resend of the authentication value. example: ENTERED required: - - responseType \ No newline at end of file + - responseType From b2419fada7740fbc54ca50b86be3cfb9e7e5d19c Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Fri, 4 Jun 2021 09:56:42 -0500 Subject: [PATCH 18/34] chore: update validateConsentRequest and validateAuthToken (#105) --- src/simulator/api.yaml | 20 +++++++++----------- src/simulator/handlers.js | 10 +++++----- src/test/simulator.js | 10 +++++----- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 86b7e853..ef7fc7cf 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -587,12 +587,12 @@ paths: application/json: schema: $ref: '#/components/schemas/errorResponse' - /validateOTP: + /validateAuthToken: post: - operationId: PostValidateOTP - summary: PostValidateOTP + operationId: PostValidateAuthToken + summary: PostValidateAuthToken description: | - The HTTP request `POST /validateOTP` is used to validate an auth token from a PISP for authentication. + The HTTP request `POST /validateAuthToken` is used to validate an auth token from a PISP for authentication. tags: - validateOTP requestBody: @@ -2035,13 +2035,11 @@ components: type: object description: The object sent in a `POST /consentRequests` request. properties: - id: + consentRequestId: $ref: '#/components/schemas/CorrelationId' - initiatorId: + userId: type: string - description: >- - The id of the PISP who will initiate transactions on a user's - behalf. + description: ID used to associate request with GET /accounts request. scopes: type: array items: @@ -2056,8 +2054,8 @@ components: The callback uri that the user will be redirected to after completing the WEB auth channel. required: - - id - - initiatorId + - consentRequestId + - userId - scopes - authChannels - callbackUri diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index 191f19b4..a7cad1d6 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -254,9 +254,9 @@ const getScopesById = async (ctx) => { ctx.response.status = 200; }; -const postValidateOTP = async (ctx) => { +const postValidateAuthToken = async (ctx) => { // fake validation for testing purposes - // even auth tokens validate true + // even auth tokens validate true as default mock response, if rules not configured const res = { isValid: ctx.request.body.authToken % 2 === 0, }; @@ -268,7 +268,7 @@ const postValidateOTP = async (ctx) => { const validateConsentRequests = async (ctx) => { const request = ctx.request.body; ctx.state.logger.log(`validateConsentRequests request body: ${util.inspect(request)}`); - // default mock reponse, if rules not configured + // default mock response, if rules not configured const res = { isValid: true, data: { @@ -370,8 +370,8 @@ const map = { '/scopes/{ID}': { get: getScopesById, }, - '/validateOTP': { - post: postValidateOTP, + '/validateAuthToken': { + post: postValidateAuthToken, }, '/validateConsentRequests': { post: validateConsentRequests, diff --git a/src/test/simulator.js b/src/test/simulator.js index 860ff887..95d9d01a 100644 --- a/src/test/simulator.js +++ b/src/test/simulator.js @@ -76,7 +76,7 @@ test('get scopes by Id', async (t) => { test('post validateConsentRequests', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { - body: { id: '123456' }, + body: { consentRequestId: '123456' }, }; await map['/validateConsentRequests'].post(t.context); t.truthy(t.context.response.body); @@ -116,7 +116,7 @@ test('get consentRequest', async (t) => { t.is(t.context.response.status, 200); }); -test('post validate otp valid', async (t) => { +test('post validate authToken valid', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { body: { @@ -124,14 +124,14 @@ test('post validate otp valid', async (t) => { consentRequestId: idValue, }, }; - await map['/validateOTP'].post(t.context); + await map['/validateAuthToken'].post(t.context); t.truthy(t.context.response.body); t.is(t.context.response.body.isValid, true); t.is(t.context.response.status, 200); }); -test('post validate otp invalid', async (t) => { +test('post validate authToken invalid', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { body: { @@ -139,7 +139,7 @@ test('post validate otp invalid', async (t) => { consentRequestId: idValue, }, }; - await map['/validateOTP'].post(t.context); + await map['/validateAuthToken'].post(t.context); t.truthy(t.context.response.body); t.is(t.context.response.body.isValid, false); t.is(t.context.response.status, 200); From 0c31dbbd1472a1239e0d817d7bc12f2ec5d2b8a8 Mon Sep 17 00:00:00 2001 From: Kevin Leyow Date: Sun, 22 Aug 2021 20:31:49 -0500 Subject: [PATCH 19/34] chore: add new endpoints to store consent info for accountId (#112) * chore: add new endpoints to store consent info for accountId * chore: address vulnerabilities * chore: update endpoints --- src/audit-resolve.json | 388 +++++++++++++++++++++-------------------- src/package-lock.json | 39 +++-- src/simulator/api.yaml | 66 ++++++- 3 files changed, 282 insertions(+), 211 deletions(-) diff --git a/src/audit-resolve.json b/src/audit-resolve.json index 3b07a41a..0b1677f0 100644 --- a/src/audit-resolve.json +++ b/src/audit-resolve.json @@ -6,34 +6,28 @@ "expiresAt": 1594863234907 }, "1589|sqlite>sqlite3>node-pre-gyp>rc>ini": { - "decision": "ignore", - "madeAt": 1620638321689, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430330895 }, "1589|00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { - "decision": "ignore", - "madeAt": 1620638321689, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430330895 }, "1589|00unidentified>00unidentified>sqlite>sqlite3>node-pre-gyp>rc>ini": { - "decision": "ignore", - "madeAt": 1620638321689, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430330896 }, "1589|ava>update-notifier>latest-version>package-json>registry-auth-token>rc>ini": { - "decision": "ignore", - "madeAt": 1620638321689, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430330896 }, "1589|ava>update-notifier>latest-version>package-json>registry-url>rc>ini": { - "decision": "ignore", - "madeAt": 1620638321689, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430330896 }, "1589|ava>update-notifier>is-installed-globally>global-dirs>ini": { - "decision": "ignore", - "madeAt": 1620638321689, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430330896 }, "1654|ava>yargs>y18n": { "decision": "fix", @@ -48,294 +42,306 @@ "madeAt": 1617075431111 }, "1673|ava>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|eslint>inquirer>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|eslint>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|eslint>table>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|npm-audit-resolver>yargs-unparser>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-module-imports>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-member-expression-to-functions>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/helper-optimise-call-expression>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/helper-get-function-arity>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335668 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/template>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-function-name>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-split-export-declaration>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-simple-access>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/types>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/traverse>@babel/generator>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>@babel/helper-replace-supers>@babel/traverse>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helpers>@babel/traverse>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/traverse>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/traverse>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>@babel/helper-module-transforms>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|nyc>istanbul-lib-instrument>@babel/core>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1673|tap-xunit>xmlbuilder>lodash": { - "decision": "ignore", - "madeAt": 1620638324097, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430335669 }, "1677|ava>read-pkg>normalize-package-data>hosted-git-info": { - "decision": "ignore", - "madeAt": 1620638325847, - "expiresAt": 1623230315330 + "decision": "fix", + "madeAt": 1629430341254 }, "1677|eslint-plugin-import>read-pkg-up>read-pkg>normalize-package-data>hosted-git-info": { + "decision": "fix", + "madeAt": 1629430341254 + }, + "1770|sqlite>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1629430325674, + "expiresAt": 1632022316110 + }, + "1771|sqlite>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1629430325674, + "expiresAt": 1632022316110 + }, + "1751|ava>chokidar>glob-parent": { + "decision": "fix", + "madeAt": 1629430345984 + }, + "1751|ava>del>globby>fast-glob>glob-parent": { + "decision": "fix", + "madeAt": 1629430345984 + }, + "1751|ava>globby>fast-glob>glob-parent": { + "decision": "fix", + "madeAt": 1629430345984 + }, + "1751|eslint>glob-parent": { + "decision": "fix", + "madeAt": 1629430345984 + }, + "1755|ava>update-notifier>latest-version>package-json>got>cacheable-request>normalize-url": { + "decision": "fix", + "madeAt": 1629430350906 + }, + "1773|ava>read-pkg>normalize-package-data>resolve>path-parse": { + "decision": "fix", + "madeAt": 1629430355918 + }, + "1773|eslint-plugin-import>read-pkg-up>read-pkg>normalize-package-data>resolve>path-parse": { + "decision": "fix", + "madeAt": 1629430355918 + }, + "1773|eslint-plugin-import>eslint-import-resolver-node>resolve>path-parse": { + "decision": "fix", + "madeAt": 1629430355918 + }, + "1773|eslint-plugin-import>resolve>path-parse": { + "decision": "fix", + "madeAt": 1629430355918 + }, + "1773|nyc>istanbul-lib-instrument>@babel/core>resolve>path-parse": { + "decision": "fix", + "madeAt": 1629430355918 + }, + "1770|00unidentified>sqlite>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1629430358453, + "expiresAt": 1632022316110 + }, + "1770|00unidentified>00unidentified>sqlite>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1629430358453, + "expiresAt": 1632022316110 + }, + "1771|00unidentified>sqlite>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1629430358453, + "expiresAt": 1632022316110 + }, + "1771|00unidentified>00unidentified>sqlite>sqlite3>node-pre-gyp>tar": { "decision": "ignore", - "madeAt": 1620638325847, - "expiresAt": 1623230315330 + "madeAt": 1629430358453, + "expiresAt": 1632022316110 } }, "rules": {}, diff --git a/src/package-lock.json b/src/package-lock.json index 70a83e81..ef941f02 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -2542,9 +2542,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2677,9 +2677,9 @@ "integrity": "sha512-YXXAAhmF9zpQbC7LEcREFtXfGq5K1fmd+4PHkBq8NUqmzW3G+Dq10bI/i0KucLRwss3YYFQ0fSfoxBZYiGUqtQ==" }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-escaper": { @@ -2848,9 +2848,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inquirer": { "version": "7.1.0", @@ -3513,9 +3513,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.clonedeep": { @@ -3863,9 +3863,9 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "npm-audit-resolver": { @@ -4341,9 +4341,9 @@ "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-type": { @@ -5790,7 +5790,8 @@ "y18n": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true }, "yallist": { "version": "3.1.1", diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index ef7fc7cf..258c4466 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -838,9 +838,73 @@ paths: schema: $ref: '#/components/schemas/errorResponse' + /store/consent: + post: + tags: + - DFSPSim + description: | + The HTTP request `POST /store/consent` is used to request that the DFSP store information about + an account ID and consent. + summary: PostStoreConsent + operationId: PostStoreConsent + requestBody: + required: true + content: + application/json: + schema: + type: object + responses: + 200: + description: Response containing details + content: + application/json: + schema: + type: object + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + + + /transactionRequestContextForAccountId/{ID}: + get: + tags: + - DFSPSim + operationId: GetTransactionRequestContextForAccountIdById + summary: GetTransactionRequestContextForAccountIdById + description: | + The HTTP request `GET /transactionRequestContextForAccountId/{ID}` is + used to retrieve consent information for a specific account ID. + responses: + 200: + description: Response containing account consent info details + content: + application/json: + schema: + type: object + 400: + description: Malformed or missing required headers or parameters + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + 500: + description: An error occured processing the request + content: + application/json: + schema: + $ref: '#/components/schemas/errorResponse' + components: schemas: - quoteRequest: type: object description: A request for a quote for transfer from the DFSP backend From ceeefae983a234bc18055990360602b1d3867f8d Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Thu, 26 Aug 2021 17:26:50 +0930 Subject: [PATCH 20/34] feat: update `ValidateThirdpartyRequestsTransactionsPostResponse` to include transaction context required by the 3p-scheme-adapter (#113) --- src/simulator/api.yaml | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 258c4466..ac8f5dbb 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -873,36 +873,6 @@ paths: schema: $ref: '#/components/schemas/errorResponse' - - /transactionRequestContextForAccountId/{ID}: - get: - tags: - - DFSPSim - operationId: GetTransactionRequestContextForAccountIdById - summary: GetTransactionRequestContextForAccountIdById - description: | - The HTTP request `GET /transactionRequestContextForAccountId/{ID}` is - used to retrieve consent information for a specific account ID. - responses: - 200: - description: Response containing account consent info details - content: - application/json: - schema: - type: object - 400: - description: Malformed or missing required headers or parameters - content: - application/json: - schema: - $ref: '#/components/schemas/errorResponse' - 500: - description: An error occured processing the request - content: - application/json: - schema: - $ref: '#/components/schemas/errorResponse' - components: schemas: quoteRequest: @@ -2253,8 +2223,14 @@ components: properties: isValid: type: boolean + payerPartyIdInfo: + $ref: '#/components/schemas/PartyIdInfo' + consentId: + $ref: '#/components/schemas/CorrelationId' required: - isValid + - payerPartyIdInfo + - consentId UserName: title: UserName type: string From 2731bed6421da433bc3d8a295c7afa8b9ec1409e Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 15:48:12 +0930 Subject: [PATCH 21/34] chore: noting conflicts --- .circleci/_set_up_deploy_envs.sh | 47 ---- .circleci/config.yml | 5 + src/package-lock.json | 446 +++++++------------------------ src/simulator/api.yaml | 64 +---- 4 files changed, 105 insertions(+), 457 deletions(-) delete mode 100755 .circleci/_set_up_deploy_envs.sh diff --git a/.circleci/_set_up_deploy_envs.sh b/.circleci/_set_up_deploy_envs.sh deleted file mode 100755 index 2dbbf695..00000000 --- a/.circleci/_set_up_deploy_envs.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash -set -o nounset - - -if [[ ${CIRCLE_TAG} =~ v[0-9]+(\.[0-9]+)*(\-snapshot) ]]; then - echo "Setting snap shot env vars for ${CIRCLE_TAG}" - - echo 'export RELEASE_TAG=$RELEASE_TAG_SNAPSHOT' >> $BASH_ENV - echo 'export HELM_VALUE_FILENAME=$K8_HELM_VALUE_FILENAME_SNAPSHOT' >> $BASH_ENV - echo 'export K8_CLUSTER_SERVER=$K8_CLUSTER_SERVER_SNAPSHOT' >> $BASH_ENV - echo 'export K8_RELEASE_NAME=$K8_RELEASE_NAME_SNAPSHOT' >> $BASH_ENV - echo 'export K8_NAMESPACE=$K8_NAMESPACE_SNAPSHOT' >> $BASH_ENV - echo 'export K8_USER_NAME=$K8_USER_NAME_SNAPSHOT' >> $BASH_ENV - echo 'export K8_USER_TOKEN=$K8_USER_TOKEN_SNAPSHOT' >> $BASH_ENV - echo 'export K8_HELM_CHART_NAME=$K8_HELM_CHART_NAME_SNAPSHOT' >> $BASH_ENV - echo 'export K8_HELM_CHART_VERSION=$K8_HELM_CHART_VERSION_SNAPSHOT' >> $BASH_ENV - echo 'export HELM_VALUE_SET_VALUES="--set central.centralhub.centralledger.containers.api.image.repository=$DOCKER_ORG/$CIRCLE_PROJECT_REPONAME --set central.centralhub.centralledger.containers.api.image.tag=$CIRCLE_TAG --set central.centralhub.centralledger.containers.admin.image.repository=$DOCKER_ORG/$CIRCLE_PROJECT_REPONAME --set central.centralhub.centralledger.containers.admin.image.tag=$CIRCLE_TAG"' >> $BASH_ENV - - exit 0 -fi - -if [[ ${CIRCLE_TAG} =~ v[0-9]+(\.[0-9]+)*(\-hotfix) ]]; then - echo "Setting hotfix env vars for ${CIRCLE_TAG}" - - echo 'export RELEASE_TAG=$RELEASE_TAG_PROD' >> $BASH_ENV - exit 0 -fi - -if [[ ${CIRCLE_TAG} =~ v[0-9]+(\.[0-9]+)* ]]; then - echo "Setting prod env vars for ${CIRCLE_TAG}" - - echo 'export RELEASE_TAG=$RELEASE_TAG_PROD' >> $BASH_ENV - echo 'export HELM_VALUE_FILENAME=$K8_HELM_VALUE_FILENAME_PROD' >> $BASH_ENV - echo 'export K8_CLUSTER_SERVER=$K8_CLUSTER_SERVER_PROD' >> $BASH_ENV - echo 'export K8_RELEASE_NAME=$K8_RELEASE_NAME_PROD' >> $BASH_ENV - echo 'export K8_NAMESPACE=$K8_NAMESPACE_PROD' >> $BASH_ENV - echo 'export K8_USER_NAME=$K8_USER_NAME_PROD' >> $BASH_ENV - echo 'export K8_USER_TOKEN=$K8_USER_TOKEN_PROD' >> $BASH_ENV - echo 'export K8_HELM_CHART_NAME=$K8_HELM_CHART_NAME_PROD' >> $BASH_ENV - echo 'export K8_HELM_CHART_VERSION=$K8_HELM_CHART_VERSION_PROD' >> $BASH_ENV - echo 'export HELM_VALUE_SET_VALUES="--set central.centralhub.centralledger.containers.api.image.repository=$DOCKER_ORG/$CIRCLE_PROJECT_REPONAME --set central.centralhub.centralledger.containers.api.image.tag=$CIRCLE_TAG --set central.centralhub.centralledger.containers.admin.image.repository=$DOCKER_ORG/$CIRCLE_PROJECT_REPONAME --set central.centralhub.centralledger.containers.admin.image.tag=$CIRCLE_TAG"' >> $BASH_ENV - - exit 0 -fi - -echo "No valid match found for CIRCLE_TAG: ${CIRCLE_TAG}" -exit 1 \ No newline at end of file diff --git a/.circleci/config.yml b/.circleci/config.yml index 1719f54b..be9ce5a8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,11 @@ # CircleCI v2.1 Config version: 2.1 + +# TODO! this config file is a real mess. +# how can we improve it? Can we also add +# auto-releases at the same time? + ## # orbs # diff --git a/src/package-lock.json b/src/package-lock.json index b89d8cea..06ad00a0 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -1,10 +1,6 @@ { "name": "mojaloop-simulator", -<<<<<<< HEAD - "version": "11.3.0", -======= "version": "11.4.3", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "lockfileVersion": 1, "requires": true, "dependencies": { @@ -693,8 +689,6 @@ "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } -<<<<<<< HEAD -======= }, "strip-ansi": { "version": "4.0.0", @@ -724,7 +718,6 @@ "requires": { "mkdirp": "^0.5.1" } ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } } }, @@ -1034,17 +1027,10 @@ "uri-js": "^4.2.2" }, "dependencies": { -<<<<<<< HEAD - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" -======= "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } } }, @@ -1215,12 +1201,30 @@ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, "audit-resolve-core": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/audit-resolve-core/-/audit-resolve-core-1.1.8.tgz", @@ -1234,22 +1238,11 @@ "yargs-parser": "^18.1.3" }, "dependencies": { -<<<<<<< HEAD - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } -======= "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "yargs-parser": { "version": "18.1.3", @@ -1327,8 +1320,6 @@ "yargs": "^16.2.0" } }, -<<<<<<< HEAD -======= "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -1339,14 +1330,11 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, -<<<<<<< HEAD -======= "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1361,7 +1349,6 @@ "tweetnacl": "^0.14.3" } }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1660,6 +1647,11 @@ "integrity": "sha512-zWEwIVqnzPkSAXOUlQnPW2oKoYb2aLQ4Q5ejdjBcnH63rfypaW34CxaeBn1VMya2XaEU3P/R2qHpWyj+l0BT1A==", "dev": true }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, "chalk": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", @@ -1854,8 +1846,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, -<<<<<<< HEAD -======= "colorette": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", @@ -1882,7 +1872,6 @@ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", "dev": true }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "common-path-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", @@ -2032,21 +2021,12 @@ "array-find-index": "^1.0.1" } }, -<<<<<<< HEAD - "curry2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/curry2/-/curry2-1.0.3.tgz", - "integrity": "sha1-OBkdVfEGC/6kfKCACThbuHj2YS8=", - "requires": { - "fast-bind": "^1.0.0" -======= "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { "assert-plus": "^1.0.0" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } }, "date-time": { @@ -2059,15 +2039,9 @@ } }, "debug": { -<<<<<<< HEAD - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", -======= "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "requires": { "ms": "2.1.2" }, @@ -2173,6 +2147,11 @@ "slash": "^3.0.0" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -2246,6 +2225,15 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2821,17 +2809,10 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, -<<<<<<< HEAD - "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==" -======= "eventemitter2": { "version": "6.4.4", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.4.tgz", "integrity": "sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw==" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "events-to-array": { "version": "1.1.2", @@ -2839,28 +2820,6 @@ "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", "dev": true }, -<<<<<<< HEAD - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "fast-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-bind/-/fast-bind-1.0.0.tgz", - "integrity": "sha1-f6llLLMyX1zR4lLWy08WDeGnbnU=" - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" -======= "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -2875,7 +2834,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "fast-diff": { "version": "1.2.0", @@ -3003,12 +2961,6 @@ "signal-exit": "^3.0.2" } }, -<<<<<<< HEAD - "format-util": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.5.tgz", - "integrity": "sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg==" -======= "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3023,7 +2975,6 @@ "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "formidable": { "version": "1.2.2", @@ -3191,6 +3142,14 @@ "pump": "^3.0.0" } }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -3285,8 +3244,6 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, -<<<<<<< HEAD -======= "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -3314,7 +3271,6 @@ } } }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3395,14 +3351,11 @@ "http-errors": "~1.7.2" }, "dependencies": { -<<<<<<< HEAD -======= "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "http-errors": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", @@ -3435,21 +3388,16 @@ "toidentifier": "1.0.0" }, "dependencies": { -<<<<<<< HEAD -======= "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" } -<<<<<<< HEAD -======= } }, "http-proxy-agent": { @@ -3471,7 +3419,6 @@ "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } }, "https-proxy-agent": { @@ -3605,64 +3552,6 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" -<<<<<<< HEAD - }, - "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, -======= }, "ip": { "version": "1.1.5", @@ -3670,7 +3559,6 @@ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", "dev": true }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "irregular-plurals": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz", @@ -3756,15 +3644,9 @@ "dev": true }, "is-generator-function": { -<<<<<<< HEAD - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz", - "integrity": "sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ==" -======= "version": "1.0.9", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "is-glob": { "version": "4.0.1", @@ -3867,15 +3749,12 @@ "has-symbols": "^1.0.2" } }, -<<<<<<< HEAD -======= "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "is-string": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", @@ -3894,8 +3773,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-unicode-supported": { "version": "0.1.0", @@ -3925,6 +3803,11 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", @@ -4062,6 +3945,11 @@ "esprima": "^4.0.0" } }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -4114,15 +4002,10 @@ } } }, - "json-schema-ref-parser": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-6.0.3.tgz", - "integrity": "sha512-Ds/0541IPed88JSiMb3CBeUsxfL5Eosc0r97z0QMSXiBJTYKZLhOAGZd8zFVfpkKaRb4zDAnumyFYxnHLmbQmw==", - "requires": { - "call-me-maybe": "^1.0.1", - "js-yaml": "^3.12.1", - "ono": "^4.0.11" - } + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-ref-parser": { "version": "9.0.7", @@ -4142,6 +4025,11 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -4157,8 +4045,6 @@ "integrity": "sha1-T80kbcXQ44aRkHxEqwAveC0dlMw=", "dev": true }, -<<<<<<< HEAD -======= "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -4181,7 +4067,6 @@ "verror": "1.10.0" } }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "keygrip": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", @@ -4294,11 +4179,6 @@ } }, "levn": { -<<<<<<< HEAD - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", -======= "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", @@ -4312,7 +4192,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "dev": true, "requires": { "figgy-pudding": "^3.5.1", @@ -4387,12 +4266,7 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", -<<<<<<< HEAD - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true -======= "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "lodash.clonedeep": { "version": "4.5.0", @@ -4473,8 +4347,6 @@ } } }, -<<<<<<< HEAD -======= "make-fetch-happen": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.0.2.tgz", @@ -4525,7 +4397,6 @@ "p-defer": "^1.0.0" } }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -4557,8 +4428,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, -<<<<<<< HEAD -======= "mem": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz", @@ -4583,7 +4452,6 @@ "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", "dev": true }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "merge-options": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz", @@ -4610,18 +4478,6 @@ } }, "mime-db": { -<<<<<<< HEAD - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" - }, - "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "requires": { - "mime-db": "1.44.0" -======= "version": "1.48.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" @@ -4632,7 +4488,6 @@ "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "requires": { "mime-db": "1.48.0" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } }, "mimic-fn": { @@ -4871,29 +4726,15 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, -<<<<<<< HEAD - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" - }, -======= ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "needle": { -<<<<<<< HEAD - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", - "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", -======= "version": "2.6.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -4921,20 +4762,15 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, -<<<<<<< HEAD -======= "node-addon-api": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" -<<<<<<< HEAD -======= }, "node-gyp": { "version": "7.1.2", @@ -5033,7 +4869,6 @@ "dev": true } } ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "node-pre-gyp": { "version": "0.11.0", @@ -5748,6 +5583,11 @@ } } }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5836,14 +5676,6 @@ "openapi-types": "^9.0.3" } }, - "openapi-jsonschema-parameters": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/openapi-jsonschema-parameters/-/openapi-jsonschema-parameters-1.1.0.tgz", - "integrity": "sha512-TCDHFK3oL842ne50EIymIXgvVbbMjohjjaieGDGW0hzbz3vJE9u3OjORB+p0IaKg5TbOsrpF8SNg3OvjcehBUg==", - "requires": { - "openapi-types": "^1.3.1" - } - }, "openapi-types": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-9.0.3.tgz", @@ -5905,8 +5737,6 @@ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "dev": true }, -<<<<<<< HEAD -======= "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", @@ -5928,7 +5758,6 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -6168,6 +5997,11 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -6356,8 +6190,6 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, -<<<<<<< HEAD -======= "promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", @@ -6383,7 +6215,6 @@ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -6409,11 +6240,6 @@ } }, "qs": { -<<<<<<< HEAD - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" -======= "version": "6.10.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", @@ -6426,7 +6252,6 @@ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "raw-body": { "version": "2.4.1", @@ -6439,14 +6264,11 @@ "unpipe": "1.0.0" }, "dependencies": { -<<<<<<< HEAD -======= "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "http-errors": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", @@ -6723,8 +6545,6 @@ "es6-error": "^4.0.1" } }, -<<<<<<< HEAD -======= "remote-git-tags": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remote-git-tags/-/remote-git-tags-3.0.0.tgz", @@ -6770,7 +6590,6 @@ } } }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7119,14 +6938,6 @@ "integrity": "sha512-dSdmSkrdIhUL7xP/fiEMfFuAo4dxb0afag3rK8T4Y9lYxE3g3fXT0J8H9qSFvmcKxnM0zEA8yvLbpdWQ8mom3g==" }, "sqlite3": { -<<<<<<< HEAD - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.2.0.tgz", - "integrity": "sha512-roEOz41hxui2Q7uYnWsjMOTry6TcNUNmp8audCx18gF10P2NknwdpF+E+HKvz/F2NvPKGGBF4NGc+ZPQ+AABwg==", - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.11.0" -======= "version": "5.0.2", "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.0.2.tgz", "integrity": "sha512-1SdTNo+BVU211Xj1csWa8lV6KM0CtucDwRyA0VHl91wEH1Mgh7RxUpI4rVvG7OhHrzCSGaVyW5g8vKvlrk9DJA==", @@ -7196,7 +7007,6 @@ "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } }, "ssri": { @@ -7477,14 +7287,6 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, -<<<<<<< HEAD - "topo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", - "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", - "requires": { - "hoek": "6.x.x" -======= "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -7492,7 +7294,6 @@ "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } }, "trim-off-newlines": { @@ -7518,6 +7319,19 @@ "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==" }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7635,15 +7449,9 @@ } }, "uri-js": { -<<<<<<< HEAD - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", -======= "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "requires": { "punycode": "^2.1.0" } @@ -7663,15 +7471,9 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { -<<<<<<< HEAD - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", -======= "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "dev": true }, "v8-compile-cache": { @@ -7704,6 +7506,16 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -7860,15 +7672,9 @@ "dev": true }, "y18n": { -<<<<<<< HEAD - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", -======= "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "dev": true }, "yallist": { @@ -7907,16 +7713,6 @@ "dev": true }, "yargs-unparser": { -<<<<<<< HEAD - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" -======= "version": "1.6.4", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.4.tgz", "integrity": "sha512-QxEx9+qEr7jwVM4ngnk95+sKZ5QXm5gx0cL97LDby0SiC8HHoUK0LPBg475JwQcRCqIVfMD8SubCWp1dEgKuwQ==", @@ -7927,15 +7723,12 @@ "flat": "^5.0.2", "is-plain-obj": "^1.1.0", "yargs": "^14.2.3" ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", -<<<<<<< HEAD -======= "dev": true }, "ansi-styles": { @@ -7951,18 +7744,8 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "dev": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -7972,7 +7755,6 @@ "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.0" -<<<<<<< HEAD } }, "color-convert": { @@ -7984,19 +7766,6 @@ "color-name": "1.1.3" } }, -======= - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", @@ -8087,14 +7856,6 @@ "dev": true }, "yargs": { -<<<<<<< HEAD - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", -======= "version": "14.2.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", @@ -8102,7 +7863,6 @@ "requires": { "cliui": "^5.0.0", "decamelize": "^1.2.0", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", @@ -8111,15 +7871,6 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", -<<<<<<< HEAD - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", -======= "yargs-parser": "^15.0.1" } }, @@ -8127,7 +7878,6 @@ "version": "15.0.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 8aa7d06b..5341d92a 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -1,3 +1,5 @@ +# TODO: we should have 2 different apis - one for the 3P SDK Outbound, another for the Mojaloop SDK outbound + openapi: 3.0.1 info: title: Mojaloop SDK Inbound Scheme Adapter API @@ -485,67 +487,6 @@ paths: application/json: schema: $ref: '#/components/schemas/errorResponse' -components: - schemas: - quoteRequest: - type: object - description: A request for a quote for transfer from the DFSP backend - required: - - quoteId - - transactionId - - to - - from - - amountType - - amount - - currency - - transactionType - - initiator - - initiatorType - properties: - quoteId: - $ref: '#/components/schemas/quoteId' - transactionId: - $ref: '#/components/schemas/transactionId' - description: Identifier for the transaction, decided by the Payer FSP during the creation of the quote - to: - $ref: '#/components/schemas/transferParty' - description: Information about the Payee in the proposed financial transaction. - from: - $ref: '#/components/schemas/transferParty' - description: Information about the Payer in the proposed financial transaction. - amountType: - $ref: '#/components/schemas/amountType' - description: 'SEND for send amount, RECEIVE for receive amount.' - amount: - $ref: '#/components/schemas/money' - description: Depending on amountType. If SEND - The amount the Payer would like to send, that is, the amount that should be withdrawn from the Payer account including any fees. The amount is updated by each participating entity in the transaction. If RECEIVE - The amount the Payee should receive, that is, the amount that should be sent to the receiver exclusive any fees. The amount is not updated by any of the participating entities. - currency: - $ref: '#/components/schemas/currency' - feesAmount: - $ref: '#/components/schemas/money' - description: The fees in the transaction. The fees element should be empty if fees should be non-disclosed. The fees element should be non-empty if fees should be disclosed. - feesCurrency: - $ref: '#/components/schemas/currency' - transactionType: - $ref: '#/components/schemas/transactionType' - description: Type of transaction for which the quote is requested. - initiator: - $ref: '#/components/schemas/initiator' - description: Specifies if the initiator of the transfer is the payer or payee - initiatorType: - $ref: '#/components/schemas/initiatorType' - description: Specifies the type of the transaction initiator - geoCode: - $ref: '#/components/schemas/geoCode' - description: Longitude and Latitude of the initiating Party. Can be used to detect fraud. - note: - type: string - minLength: 1 - maxLength: 128 - description: An optional note associated with the requested transfer - expiration: - $ref: '#/components/schemas/timestamp' - description: An optional deadline for responding to the quote request /bulkQuotes/{idValue}: get: @@ -644,7 +585,6 @@ components: schema: $ref: '#/components/schemas/errorResponse' - /signchallenge: post: summary: Requests a signed challenge From 6226d4037415226ab5470660063ba8406cafc878 Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 15:54:20 +0930 Subject: [PATCH 22/34] chore: resolving conflicts --- src/index.js | 4 ---- src/models/constants.js | 10 ---------- src/models/model.js | 10 ---------- src/models/party.js | 32 -------------------------------- src/simulator/handlers.js | 15 +++++++++++++++ 5 files changed, 15 insertions(+), 56 deletions(-) diff --git a/src/index.js b/src/index.js index d3e9ce09..9ab9d5e1 100644 --- a/src/index.js +++ b/src/index.js @@ -168,12 +168,8 @@ async function rewriteContentTypeHeader(ctx, next) { ctx.state.logger.push({ response: { body, status } }).log('Request processed'); }); -<<<<<<< HEAD simulator.use(rewriteContentTypeHeader); -======= testApi.use(cors()); ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - simulator.use(koaBody()); report.use(koaBody()); testApi.use(koaBody()); diff --git a/src/models/constants.js b/src/models/constants.js index fb75d184..605b6b99 100644 --- a/src/models/constants.js +++ b/src/models/constants.js @@ -121,7 +121,6 @@ CREATE TABLE IF NOT EXISTS ${bulkTransferTable} ( ) `; -<<<<<<< HEAD const createAccountTable = ` CREATE TABLE IF NOT EXISTS ${partyAccountsTable} ( address TEXT NOT NULL PRIMARY KEY, @@ -131,8 +130,6 @@ CREATE TABLE IF NOT EXISTS ${partyAccountsTable} ( ) `; -======= ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee module.exports = { partyTable, quoteTable, @@ -145,7 +142,6 @@ module.exports = { createQuoteTable, createBulkQuoteTable, createBulkTransferTable, -<<<<<<< HEAD createTransactionRequestTable, createTransferTable, createPartyExtensionTable, @@ -153,11 +149,5 @@ module.exports = { createPartyExtensionTableUniqueIndex, partyAccountsTable, createAccountTable, -======= createTransferTable, - createTransactionRequestTable, - createPartyExtensionTable, - createPartyTableUniqueIndex, - createPartyExtensionTableUniqueIndex, ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee }; diff --git a/src/models/model.js b/src/models/model.js index cc7c7024..a559887f 100644 --- a/src/models/model.js +++ b/src/models/model.js @@ -48,10 +48,7 @@ const { createTransactionRequestTable, createPartyExtensionTable, createPartyExtensionTableUniqueIndex, -<<<<<<< HEAD createAccountTable, -======= ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } = require('./constants'); /** @@ -96,14 +93,10 @@ module.exports = class Model { throw new Error('Attempted to initialise database twice'); } -<<<<<<< HEAD - this.db = await sqlite.open(databaseFilepath); -======= this.db = await sqlite.open({ filename: databaseFilepath, driver: sqlite3.Database, }); ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee await this.db.run('PRAGMA foreign_keys = true'); await this.db.run(createPartyTable); await this.db.run(createPartyTableUniqueIndex); @@ -114,10 +107,7 @@ module.exports = class Model { await this.db.run(createPartyExtensionTableUniqueIndex); await this.db.run(createBulkQuoteTable); await this.db.run(createBulkTransferTable); -<<<<<<< HEAD await this.db.run(createAccountTable); -======= ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee this.party = new Party(this.db); this.quote = new Quote(this.db); diff --git a/src/models/party.js b/src/models/party.js index 8223e26c..2315303a 100644 --- a/src/models/party.js +++ b/src/models/party.js @@ -53,27 +53,11 @@ module.exports = class Party { async get(idType, idValue, subIdValue = null) { let res; if (!subIdValue) { -<<<<<<< HEAD - res = await this.db.all(` - SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value, pa.address, pa.currency, pa.description - FROM ${partyTable} p - LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue - LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue - WHERE p.idType = ? AND p.idValue = ? AND p.subIdValue IS NULL AND pe.subIdValue IS NULL`, [idType, idValue]); - } else { - res = await this.db.all(` - SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value, pa.address, pa.currency, pa.description - FROM ${partyTable} p - LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue AND p.subIdValue = pe.subIdValue - LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue - WHERE p.idType = ? AND p.idValue = ? AND p.subIdValue = ?`, [idType, idValue, subIdValue]); -======= res = await this.db.all(`SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value FROM ${partyTable} p LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue WHERE p.idType = ? AND p.idValue = ? AND p.subIdValue IS NULL AND pe.subIdValue IS NULL`, [idType, idValue]); } else { res = await this.db.all(`SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value FROM ${partyTable} p LEFT JOIN ${partyExtensionTable} pe ON p.idValue = pe.idValue AND p.subIdValue = pe.subIdValue WHERE p.idType = ? AND p.idValue = ? AND p.subIdValue = ?`, [idType, idValue, subIdValue]); ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } const resultMap = {}; res.forEach((row) => { @@ -91,11 +75,7 @@ module.exports = class Party { idValue: row.idValue, }; if (row.subIdValue) { -<<<<<<< HEAD party.subIdValue = row.subIdValue; -======= - party.idSubValue = row.subIdValue; ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } resultMap[row.idValue] = party; } @@ -129,17 +109,9 @@ module.exports = class Party { * @returns {Promise} Party object. */ async getAll() { -<<<<<<< HEAD - const res = await this.db.all(` - SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value, pa.address, pa.currency, pa.description - FROM ${partyTable} p - LEFT JOIN ${partyExtensionTable} pe ON (p.idValue = pe.idValue AND pe.subIdValue IS NULL AND p.subIdValue IS NULL) OR (p.idValue = pe.idValue AND p.subIdValue = pe.subIdValue) - LEFT JOIN ${partyAccountsTable} pa ON p.idValue = pa.idValue`); -======= const res = await this.db.all(`SELECT p.displayName, p.firstName, p.middleName, p.lastName, p.dateOfBirth, p.idType, p.idValue, p.subIdValue, pe.key, pe.value FROM ${partyTable} p LEFT JOIN ${partyExtensionTable} pe ON (p.idValue = pe.idValue AND pe.subIdValue IS NULL AND p.subIdValue IS NULL) OR (p.idValue = pe.idValue AND p.subIdValue = pe.subIdValue)`); ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee const resultMap = {}; res.forEach((row) => { let party; @@ -156,11 +128,7 @@ module.exports = class Party { idValue: row.idValue, }; if (row.subIdValue) { -<<<<<<< HEAD party.subIdValue = row.subIdValue; -======= - party.idSubValue = row.subIdValue; ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee } resultMap[`${row.idValue}-${row.subIdValue}`] = party; } diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index 1225a4f1..b683db24 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -302,6 +302,21 @@ const getConsentRequest = async (ctx) => { ctx.response.status = 200; }; +const getSignedChallenge = async (ctx) => { + try { + const res = { + pinValue: crypto.randomBytes(256).toString('base64').slice(0, 64), + counter: '1', + }; + ctx.state.logger.log(`getSignedChallenge is returning body: ${util.inspect(res)}`); + ctx.response.body = res; + ctx.response.status = 200; + } catch (err) { + ctx.response.body = ApiErrorCodes.SERVER_ERROR; + ctx.response.status = 500; + } +}; + const map = { '/': { get: healthCheck, From 9f57395196476b2b2b0749ccb393066db576a820 Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 15:56:24 +0930 Subject: [PATCH 23/34] chore: resolving conflicts --- src/simulator/api.yaml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/simulator/api.yaml b/src/simulator/api.yaml index 5341d92a..4d706921 100644 --- a/src/simulator/api.yaml +++ b/src/simulator/api.yaml @@ -3128,13 +3128,12 @@ components: - completedTimestamp - transferState - - - SEND - Amount the Payer would like to send, that is, the amount that - should be withdrawn from the Payer account including any fees. - - - RECEIVE - Amount the Payer would like the Payee to receive, that is, - the amount that should be sent to the receiver exclusive of any fees. - example: RECEIVE + # TODO: tidy me! + # - SEND - Amount the Payer would like to send, that is, the amount that + # should be withdrawn from the Payer account including any fees. + # - RECEIVE - Amount the Payer would like the Payee to receive, that is, + # the amount that should be sent to the receiver exclusive of any fees. + # example: RECEIVE ThirdpartyRequestsTransactionsPostRequest: title: ThirdpartyRequestsTransactionsPostRequest type: object From 3af8d39cb87a7c2bea85ac98dc878be31c27bad6 Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 16:05:45 +0930 Subject: [PATCH 24/34] fix: unit --- src/test/constants.js | 256 +++++++++++------------------------------- src/test/model.js | 37 +++--- 2 files changed, 82 insertions(+), 211 deletions(-) diff --git a/src/test/constants.js b/src/test/constants.js index 60028fa1..a5166078 100644 --- a/src/test/constants.js +++ b/src/test/constants.js @@ -95,38 +95,6 @@ const partyCreate = { ], }; -const partyCreateWithSubIdValue = { - displayName: randName, - firstName: randName.split(' ')[0] || '', - middleName: randName.split(' ')[1] || '', - lastName: randName.split(' ')[2] || '', - dateOfBirth: '1970-01-01T00:00:00.000Z', - idType, - idValue, - subIdValue, - extensionList: [ - { - key: 'accountType', - value: 'Wallet', - }, - { - key: 'accountNumber', - value: '12345343', - }, - ], - accounts: [ - { - currency: 'USD', - description: 'savings', - address: 'moja.green.e1f3c3e0-a00f-49b6-a331-280fdd1b2c32', - }, - { - currency: 'USD', - description: 'checking', - address: 'moja.green.6de1a4af-faca-4f08-ac21-f5e3a5203f49', - }, - ], -}; const partyCreateWithSubIdValue = { displayName: randName, @@ -170,81 +138,6 @@ const quote = { initiatorType: 'CONSUMER', }; -const newQuote = { - quoteId: uuid(), - transactionId: uuid(), - to: { - idType: 'MSISDN', - idValue: '0012345', - }, - from: { - idType: 'MSISDN', - idValue: '0067890', - }, - amountType: 'SEND', - amount: '100', - currency: 'USD', - feesAmount: '0.5', - feesCurrency: 'USD', - transactionType: 'TRANSFER', - initiator: 'PAYER', - initiatorType: 'CONSUMER', -}; - -const bulkQuote = { - bulkQuoteId: idValue, - from: { - idType: 'MSISDN', - idValue: '0067890', - }, - individualQuotes: [ - { - quoteId: idValue, - transactionId: uuid(), - to: { - idType: 'MSISDN', - idValue: '0012345', - }, - amountType: 'SEND', - amount: '100', - currency: 'USD', - feesAmount: '0.5', - feesCurrency: 'USD', - transactionType: 'TRANSFER', - initiator: 'PAYER', - initiatorType: 'CONSUMER', - }, - ], -}; - -const newBulkQuote = { - bulkQuoteId: uuid(), - from: { - idType: 'MSISDN', - idValue: '0067890', - }, - individualQuotes: [ - { - quoteId: uuid(), - transactionId: uuid(), - to: { - idType: 'MSISDN', - idValue: '0012345', - }, - amountType: 'SEND', - amount: '100', - currency: 'USD', - feesAmount: '0.5', - feesCurrency: 'USD', - transactionType: 'TRANSFER', - initiator: 'PAYER', - initiatorType: 'CONSUMER', - }, - ], -}; - -const transactionrequest = { - transactionRequestId, const quoteWithExtensionList = { quoteId: idValue, transactionId: uuid(), @@ -278,57 +171,6 @@ const quoteWithExtensionList = { }, }; -const authorizationRequest = { - authenticationType: 'U2F', - retriesLeft: '1', - amount: { - currency: 'USD', - amount: '100', - }, - transactionId: '2f169631-ef99-4cb1-96dc-91e8fc08f539', - transactionRequestId: '02e28448-3c05-4059-b5f7-d518d0a2d8ea', - quote: { - transferAmount: { - currency: 'USD', - amount: '100', - }, - payeeReceiveAmount: { - currency: 'USD', - amount: '99', - }, - payeeFspFee: { - currency: 'USD', - amount: '1', - }, - payeeFspCommission: { - currency: 'USD', - amount: '0', - }, - expiration: '2020-05-17T15:28:54.250Z', - geoCode: { - latitude: '+45.4215', - longitude: '+75.6972', - }, - ilpPacket: 'AYIBgQAAAAAAAASwNGxldmVsb25lLmRmc3AxLm1lci45T2RTOF81MDdqUUZERmZlakgy...', - condition: 'f5sqb7tBTWPd5Y8BDFdMm9BJR_MNI4isf8p8n4D5pHA', - extensionList: { - extension: [ - { - key: 'errorDescription1', - value: 'This is a more detailed error description', - }, - ], - }, - }, -}; - -const transfer = { - transferId, - quote: { - quoteId: idValue, - transactionId: randName, - transferAmount: amount, - transferAmountCurrency: currency, const newQuote = { quoteId: uuid(), transactionId: uuid(), @@ -348,39 +190,6 @@ const newQuote = { transactionType: 'TRANSFER', initiator: 'PAYER', initiatorType: 'CONSUMER', - extensionList: { - extension: [ - { - key: 'KYCPayerTier', - value: '1', - }, - { - key: 'KYCNationality', - value: 'CI', - }, - ], - }, -}; - -const newQuoteWithExtensionList = { - quoteId: uuid(), - transactionId: uuid(), - to: { - idType: 'MSISDN', - idValue: '0012345', - }, - from: { - idType: 'MSISDN', - idValue: '0067890', - }, - amountType: 'SEND', - amount: '100', - currency: 'USD', - feesAmount: '0.5', - feesCurrency: 'USD', - transactionType: 'TRANSFER', - initiator: 'PAYER', - initiatorType: 'CONSUMER', }; const bulkQuote = { @@ -569,6 +378,71 @@ const transferWithoutQuote = { amount, }; +const newQuoteWithExtensionList = { + quoteId: uuid(), + transactionId: uuid(), + to: { + idType: 'MSISDN', + idValue: '0012345', + }, + from: { + idType: 'MSISDN', + idValue: '0067890', + }, + amountType: 'SEND', + amount: '100', + currency: 'USD', + feesAmount: '0.5', + feesCurrency: 'USD', + transactionType: 'TRANSFER', + initiator: 'PAYER', + initiatorType: 'CONSUMER', +}; + +const authorizationRequest = { + authenticationType: 'U2F', + retriesLeft: '1', + amount: { + currency: 'USD', + amount: '100', + }, + transactionId: '2f169631-ef99-4cb1-96dc-91e8fc08f539', + transactionRequestId: '02e28448-3c05-4059-b5f7-d518d0a2d8ea', + quote: { + transferAmount: { + currency: 'USD', + amount: '100', + }, + payeeReceiveAmount: { + currency: 'USD', + amount: '99', + }, + payeeFspFee: { + currency: 'USD', + amount: '1', + }, + payeeFspCommission: { + currency: 'USD', + amount: '0', + }, + expiration: '2020-05-17T15:28:54.250Z', + geoCode: { + latitude: '+45.4215', + longitude: '+75.6972', + }, + ilpPacket: 'AYIBgQAAAAAAAASwNGxldmVsb25lLmRmc3AxLm1lci45T2RTOF81MDdqUUZERmZlakgy...', + condition: 'f5sqb7tBTWPd5Y8BDFdMm9BJR_MNI4isf8p8n4D5pHA', + extensionList: { + extension: [ + { + key: 'errorDescription1', + value: 'This is a more detailed error description', + }, + ], + }, + }, +}; + test('constants', async (t) => { // to avoid test warnings t.pass(); diff --git a/src/test/model.js b/src/test/model.js index 0304af71..c177631e 100644 --- a/src/test/model.js +++ b/src/test/model.js @@ -168,30 +168,27 @@ test('create and update a party without extensionList', async (t) => { await model.party.create(partyCreate); const orig = await model.party.get(idType, idValue); await model.party.update(newParty, idType, idValue); -<<<<<<< HEAD -======= const changed = await model.party.get(idType, idValue); t.notDeepEqual({ orig }, { changed }); }); -test('create and update a party without extensionList', async (t) => { - const { model } = t.context; - const newParty = { - displayName: 'randName', - firstName: 'hello', - middleName: 'world', - lastName: 'lambda', - dateOfBirth: '1970-01-01T00:00:00.000Z', - idType, - idValue, - }; - await model.party.create(partyCreate); - const orig = await model.party.get(idType, idValue); - await model.party.update(newParty, idType, idValue); ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - const changed = await model.party.get(idType, idValue); - t.notDeepEqual({ orig }, { changed }); -}); +// test('create and update a party without extensionList', async (t) => { +// const { model } = t.context; +// const newParty = { +// displayName: 'randName', +// firstName: 'hello', +// middleName: 'world', +// lastName: 'lambda', +// dateOfBirth: '1970-01-01T00:00:00.000Z', +// idType, +// idValue, +// }; +// await model.party.create(partyCreate); +// const orig = await model.party.get(idType, idValue); +// await model.party.update(newParty, idType, idValue); +// const changed = await model.party.get(idType, idValue); +// t.notDeepEqual({ orig }, { changed }); +// }); test('create and update a party with subIdValue', async (t) => { const { model } = t.context; From 7bd7f58fce9c28f2f742915456c491ffa0ffe1cb Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 16:15:20 +0930 Subject: [PATCH 25/34] fix(vulns): run npm audit, fix and ignore unfixable low and moderate for 1 month --- src/audit-resolve.json | 236 +++++++++++++++++++++++++++++++++++++++++ src/package.json | 4 +- 2 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 src/audit-resolve.json diff --git a/src/audit-resolve.json b/src/audit-resolve.json new file mode 100644 index 00000000..1a652648 --- /dev/null +++ b/src/audit-resolve.json @@ -0,0 +1,236 @@ +{ + "decisions": { + "1770|npm-check-updates>pacote>@npmcli/run-script>node-gyp>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1770|npm-check-updates>pacote>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1770|npm-check-updates>pacote>npm-registry-fetch>make-fetch-happen>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1770|npm-check-updates>pacote>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1771|npm-check-updates>pacote>@npmcli/run-script>node-gyp>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1771|npm-check-updates>pacote>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1771|npm-check-updates>pacote>npm-registry-fetch>make-fetch-happen>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1771|npm-check-updates>pacote>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1779|npm-check-updates>pacote>@npmcli/run-script>node-gyp>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1779|npm-check-updates>pacote>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1779|npm-check-updates>pacote>npm-registry-fetch>make-fetch-happen>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1779|npm-check-updates>pacote>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1780|npm-check-updates>pacote>@npmcli/run-script>node-gyp>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1780|npm-check-updates>pacote>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1780|npm-check-updates>pacote>npm-registry-fetch>make-fetch-happen>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1780|npm-check-updates>pacote>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1781|npm-check-updates>pacote>@npmcli/run-script>node-gyp>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1781|npm-check-updates>pacote>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1781|npm-check-updates>pacote>npm-registry-fetch>make-fetch-happen>cacache>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1781|npm-check-updates>pacote>tar": { + "decision": "fix", + "madeAt": 1633416289000 + }, + "1770|sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1770|00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1770|00unidentified>00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1770|sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1770|00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1770|00unidentified>00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1771|sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1771|00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1771|00unidentified>00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1771|sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1771|00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1771|00unidentified>00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1779|sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1779|00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1779|00unidentified>00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1779|sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1779|00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1779|00unidentified>00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1780|sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1780|00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1780|00unidentified>00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1780|sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1780|00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1780|00unidentified>00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1781|sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1781|00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1781|00unidentified>00unidentified>sqlite3>node-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1781|sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1781|00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + }, + "1781|00unidentified>00unidentified>sqlite3>node-pre-gyp>tar": { + "decision": "ignore", + "madeAt": 1633416304667, + "expiresAt": 1636008277840 + } + }, + "rules": {}, + "version": 1 +} \ No newline at end of file diff --git a/src/package.json b/src/package.json index 8d29735b..297fa32e 100644 --- a/src/package.json +++ b/src/package.json @@ -36,8 +36,8 @@ "test:coverage-check": "nyc ava", "test:integration": "echo 'No test specified' && exit 1", "test:functional": "echo 'No test specified' && exit 1", - "audit:resolve": "SHELL=sh resolve-audit", - "audit:check": "SHELL=sh check-audit", + "audit:resolve": "SHELL=sh resolve-audit --production", + "audit:check": "SHELL=sh check-audit --production", "dep:check": "npx ncu -e 2", "dep:update": "npx ncu -u", "dep:check:lib-log": "npx ncu -e 2 --packageFile ./lib/log/package.json", From fbd895a69e8947fdb037f2cb2f871dbf3ae50e8e Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 16:22:03 +0930 Subject: [PATCH 26/34] fix: cleaning up circleci --- .circleci/config.yml | 1321 +++++++++++++++++------------------------- src/package.json | 6 +- 2 files changed, 537 insertions(+), 790 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index be9ce5a8..d6e715ed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,108 +34,6 @@ defaults_Dependencies: &defaults_Dependencies | npm install -g node-gyp defaults_awsCliDependencies: &defaults_awsCliDependencies | -<<<<<<< HEAD - apk upgrade --no-cache - apk --no-cache add \ - python3 \ - py3-pip \ - groff \ - less \ - mailcap - pip3 install --upgrade pip awscli==1.14.5 s3cmd==2.0.1 python-magic - -defaults_build_docker_build: &defaults_build_docker_build - name: Build Docker image - command: | - docker build -t $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG . - -defaults_build_docker_login: &defaults_build_docker_login - name: Login to Docker Hub - command: | - docker login -u $DOCKER_USER -p $DOCKER_PASS - -defaults_build_docker_publish: &defaults_build_docker_publish - name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub - command: | - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG - case "$CIRCLE_TAG" in - *-pisp*) - # Don't update `late5t` for an image that has a `-pisp` - echo 'skipping late5t tag' - exit 0 - ;; - *) - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - ;; - esac - -defaults_deploy_config_kubernetes_cluster: &defaults_deploy_config_kubernetes_cluster - name: Configure Kubernetes cluster - command: | - echo "Configure Kubernetes cluster ${K8_CLUSTER_NAME}" - kubectl config set-cluster $K8_CLUSTER_NAME --server=$K8_CLUSTER_SERVER --insecure-skip-tls-verify=true - -defaults_deploy_config_kubernetes_context: &defaults_deploy_config_kubernetes_context - name: Confi gure Kubernetes context - command: | - echo "Configure Kubernetes context ${K8_CLUSTER_NAME}" - kubectl config set-context $K8_CLUSTER_NAME --cluster=$K8_CLUSTER_NAME --user=$K8_USER_NAME --namespace=$K8_NAMESPACE - -defaults_deploy_config_kubernetes_credentials: &defaults_deploy_config_kubernetes_credentials - name: Configure Kubernetes credentails - command: | - echo "Configure Kubernetes credentials ${K8_USER_NAME}" - if [ ! -z "$K8_USER_TOKEN" ]; - then - echo "Configure Kubernetes credentials ${K8_USER_NAME} using Token" - kubectl config set-credentials $K8_USER_NAME --token=$K8_USER_TOKEN - else - echo "Configure Kubernetes credentials ${K8_USER_NAME} using Certs" - kubectl config set-credentials $K8_USER_NAME --client-certificate=$CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/$K8_USER_PEM_CERT_FILENAME --client-key=$CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/$K8_USER_PEM_KEY_FILENAME - fi - -defaults_deploy_configure_helm: &defaults_deploy_configure_helm - name: Configure Helm - command: | - helm init --client-only - -defaults_deploy_install_or_upgrade_helm_chart: &defaults_deploy_install_or_upgrade_helm_chart - name: Install or Upgrade Helm Chart - command: | - echo "Install or Upgrade Chart ${K8_RELEASE_NAME} for Docker Image ${DOCKER_ORG}/${CIRCLE_PROJECT_REPONAME}:${CIRCLE_TAG}" - if [ -z "$(helm list -q | grep -E "^${K8_RELEASE_NAME}$")" ] && [ "$(helm list -q | grep -E "^${K8_RELEASE_NAME}$")" != "Error: Unauthorized" ]; - then - echo "Installing ${K8_RELEASE_NAME} new release" - helm install --namespace=$K8_NAMESPACE --name=$K8_RELEASE_NAME --repo=$K8_HELM_REPO $HELM_VALUE_SET_VALUES -f $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM/$HELM_VALUE_FILENAME $K8_HELM_CHART_NAME - else - echo "Upgrading ${K8_RELEASE_NAME} release" - helm upgrade $K8_RELEASE_NAME --repo=$K8_HELM_REPO --reuse-values $HELM_VALUE_SET_VALUES -f $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM/$HELM_VALUE_FILENAME $K8_HELM_CHART_NAME - fi - -defaults_deploy_prequisites: &defaults_deploy_prequisites - name: Copy deployment pre-requisites from S3 bucket - command: | - if [ -z "$K8_USER_TOKEN" ]; - then - echo "Copying K8 keys into $AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS folder" - mkdir $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS - aws s3 cp $AWS_S3_URI_DEVOPS_DEPLOYMENT_CONFIG/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/$K8_USER_PEM_KEY_FILENAME $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/ - aws s3 cp $AWS_S3_URI_DEVOPS_DEPLOYMENT_CONFIG/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/$K8_USER_PEM_CERT_FILENAME $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS/ - else - echo "Skipping K8 keys into $AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_KEYS folder" - fi - echo "Copying Helm value file into $AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM folder for $K8_RELEASE_NAME release" - mkdir $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM - aws s3 cp $AWS_S3_URI_DEVOPS_DEPLOYMENT_CONFIG/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM/$HELM_VALUE_FILENAME $CIRCLE_WORKING_DIRECTORY/$AWS_S3_DIR_DEVOPS_DEPLOYMENT_CONFIG_HELM/ - -defaults_deploy_set_kubernetes_context: &defaults_deploy_set_kubernetes_context - name: Set Kubernetes context - command: | - echo "Configure Kubernetes context ${K8_CLUSTER_NAME}" - kubectl config use-context $K8_CLUSTER_NAME -======= apk --update --no-cache add \ python3 \ py3-pip \ @@ -143,7 +41,6 @@ defaults_deploy_set_kubernetes_context: &defaults_deploy_set_kubernetes_context less \ mailcap pip3 install --upgrade awscli==1.14.5 s3cmd==2.0.1 python-magic ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee defaults_license_scanner: &defaults_license_scanner name: Install and set up license-scanner @@ -151,24 +48,6 @@ defaults_license_scanner: &defaults_license_scanner git clone https://github.com/mojaloop/license-scanner /tmp/license-scanner cd /tmp/license-scanner && make build default-files set-up -<<<<<<< HEAD - -# defaults_working_directory: &defaults_working_directory -# # The working directory for this project (place where package.json is) is /src, -# # as opposed to the project root -# working_directory: /home/circleci/project/git - -defaults_slack_announcement: &defaults_slack_announcement - name: Slack announcement for tag releases - command: | - curl -X POST \ - $SLACK_WEBHOOK_ANNOUNCEMENT \ - -H 'Content-type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - -======= ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee src_working_directory: &src_working_directory # The working directory for this project (place where package.json is) is /src, # as opposed to the project root @@ -183,25 +62,13 @@ executors: default-docker: working_directory: /home/circleci/project/git docker: -<<<<<<< HEAD - - image: node:12.16.0-alpine -======= - image: node:12.18.0-alpine ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee default-machine: working_directory: /home/circleci/project/git machine: image: ubuntu-1604:201903-01 -<<<<<<< HEAD - helm-kube: - working_directory: /home/circleci/project - docker: - - image: hypnoglow/kubernetes-helm - -======= ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee ## # Jobs # @@ -214,16 +81,6 @@ jobs: - run: name: Install general dependencies command: *defaults_Dependencies -<<<<<<< HEAD - - checkout - # - run: - # name: Build dependencies - # command: apk add --no-cache -t build-dependencies make gcc g++ python libtool autoconf automake - - run: - name: Access npm folder as root - command: cd $(npm root -g)/npm -======= ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - run: name: Update NPM install (using `npm ci`) command: cd src && npm ci @@ -240,12 +97,9 @@ jobs: test-unit: executor: default-docker steps: -<<<<<<< HEAD - run: name: Install general dependencies command: *defaults_Dependencies -======= ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - checkout - restore_cache: key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} @@ -271,8 +125,6 @@ jobs: test-coverage: executor: default-docker steps: -<<<<<<< HEAD -======= - checkout - restore_cache: key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} @@ -280,7 +132,6 @@ jobs: - src/node_modules - src/lib/log/node_modules - src/lib/validate/node_modules ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - run: name: Install general dependencies command: *defaults_Dependencies @@ -310,11 +161,6 @@ jobs: vulnerability-check: executor: default-docker steps: -<<<<<<< HEAD - - run: - name: Install general dependencies - command: *defaults_Dependencies -======= - checkout - restore_cache: key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} @@ -338,7 +184,6 @@ jobs: vulnerability-check-onboard-hub-accounts: executor: default-docker steps: ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - checkout - restore_cache: key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} @@ -357,12 +202,7 @@ jobs: command: mkdir -p ./audit/results - run: name: Check for new npm vulnerabilities -<<<<<<< HEAD - command: npm run audit:check --silent -- --json > ./audit/results/auditResults.json - <<: *src_working_directory -======= command: cd src && npm run audit:check --silent -- --json > ../audit/results/auditResults.json ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - store_artifacts: path: ./audit/results prefix: audit @@ -396,8 +236,6 @@ jobs: audit-licenses: executor: default-docker steps: -<<<<<<< HEAD -======= - checkout - restore_cache: key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} @@ -405,11 +243,9 @@ jobs: - src/node_modules - src/lib/log/node_modules - src/lib/validate/node_modules ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - run: name: Install general dependencies command: *defaults_Dependencies - - checkout - run: <<: *defaults_license_scanner - run: @@ -423,6 +259,7 @@ jobs: executor: default-machine steps: - checkout + # TODO: build all the images here! - run: name: Build Docker $CIRCLE_TAG image command: > @@ -442,166 +279,166 @@ jobs: paths: - ./docker-image.tar - build-onboard-hub-accounts: - executor: default-machine - steps: - - checkout - - run: - name: Build Docker onboard-hub-accounts $CIRCLE_TAG image - command: > - echo "Building Docker image: onboard-hub-accounts $CIRCLE_TAG" + # build-onboard-hub-accounts: + # executor: default-machine + # steps: + # - checkout + # - run: + # name: Build Docker onboard-hub-accounts $CIRCLE_TAG image + # command: > + # echo "Building Docker image: onboard-hub-accounts $CIRCLE_TAG" - docker build - --build-arg CREATED="$(date -u --iso-8601=seconds)" - --build-arg VERSION="$RELEASE_TAG" - --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - --build-arg REVISION="$CIRCLE_SHA1" - -t $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG ./init/onboard-hub-accounts/ - - run: - name: Save docker image to workspace - command: docker save -o /tmp/docker-onboard-hub-accounts.tar $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG - - persist_to_workspace: - root: /tmp - paths: - - ./docker-onboard-hub-accounts.tar + # docker build + # --build-arg CREATED="$(date -u --iso-8601=seconds)" + # --build-arg VERSION="$RELEASE_TAG" + # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + # --build-arg REVISION="$CIRCLE_SHA1" + # -t $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG ./init/onboard-hub-accounts/ + # - run: + # name: Save docker image to workspace + # command: docker save -o /tmp/docker-onboard-hub-accounts.tar $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG + # - persist_to_workspace: + # root: /tmp + # paths: + # - ./docker-onboard-hub-accounts.tar - build-onboard-central-ledger: - executor: default-machine - steps: - - checkout - - run: - name: Build Docker onboard-central-ledger $CIRCLE_TAG image - command: > - echo "Building Docker image: onboard-central-ledger $CIRCLE_TAG" + # build-onboard-central-ledger: + # executor: default-machine + # steps: + # - checkout + # - run: + # name: Build Docker onboard-central-ledger $CIRCLE_TAG image + # command: > + # echo "Building Docker image: onboard-central-ledger $CIRCLE_TAG" - docker build - --build-arg CREATED="$(date -u --iso-8601=seconds)" - --build-arg VERSION="$RELEASE_TAG" - --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - --build-arg REVISION="$CIRCLE_SHA1" - -t $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG ./init/onboard-central-ledger/ - - run: - name: Save docker image to workspace - command: docker save -o /tmp/docker-onboard-central-ledger.tar $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG - - persist_to_workspace: - root: /tmp - paths: - - ./docker-onboard-central-ledger.tar + # docker build + # --build-arg CREATED="$(date -u --iso-8601=seconds)" + # --build-arg VERSION="$RELEASE_TAG" + # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + # --build-arg REVISION="$CIRCLE_SHA1" + # -t $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG ./init/onboard-central-ledger/ + # - run: + # name: Save docker image to workspace + # command: docker save -o /tmp/docker-onboard-central-ledger.tar $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG + # - persist_to_workspace: + # root: /tmp + # paths: + # - ./docker-onboard-central-ledger.tar - build-onboard-msisdn-oracle: - executor: default-machine - steps: - - checkout - - run: - name: Build Docker onboard-msisdn-oracle $CIRCLE_TAG image - command: > - echo "Building Docker image: onboard-msisdn-oracle $CIRCLE_TAG" + # build-onboard-msisdn-oracle: + # executor: default-machine + # steps: + # - checkout + # - run: + # name: Build Docker onboard-msisdn-oracle $CIRCLE_TAG image + # command: > + # echo "Building Docker image: onboard-msisdn-oracle $CIRCLE_TAG" - docker build - --build-arg CREATED="$(date -u --iso-8601=seconds)" - --build-arg VERSION="$RELEASE_TAG" - --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - --build-arg REVISION="$CIRCLE_SHA1" - -t $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG ./init/onboard-msisdn-oracle/ - - run: - name: Save docker image to workspace - command: docker save -o /tmp/docker-onboard-msisdn-oracle.tar $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG - - persist_to_workspace: - root: /tmp - paths: - - ./docker-onboard-msisdn-oracle.tar + # docker build + # --build-arg CREATED="$(date -u --iso-8601=seconds)" + # --build-arg VERSION="$RELEASE_TAG" + # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + # --build-arg REVISION="$CIRCLE_SHA1" + # -t $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG ./init/onboard-msisdn-oracle/ + # - run: + # name: Save docker image to workspace + # command: docker save -o /tmp/docker-onboard-msisdn-oracle.tar $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG + # - persist_to_workspace: + # root: /tmp + # paths: + # - ./docker-onboard-msisdn-oracle.tar - build-local: - executor: default-machine - steps: - - checkout - - run: - name: Build Docker local image for testing - command: > - echo "Building Docker image: local" + # build-local: + # executor: default-machine + # steps: + # - checkout + # - run: + # name: Build Docker local image for testing + # command: > + # echo "Building Docker image: local" - docker build - --build-arg CREATED="$(date -u --iso-8601=seconds)" - --build-arg VERSION="local" - --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - --build-arg REVISION="$CIRCLE_SHA1" - -t mojaloop/$CIRCLE_PROJECT_REPONAME:local . - - run: - name: Save docker image to workspace - command: docker save -o /tmp/docker-image.tar mojaloop/$CIRCLE_PROJECT_REPONAME:local - - persist_to_workspace: - root: /tmp - paths: - - ./docker-image.tar + # docker build + # --build-arg CREATED="$(date -u --iso-8601=seconds)" + # --build-arg VERSION="local" + # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + # --build-arg REVISION="$CIRCLE_SHA1" + # -t mojaloop/$CIRCLE_PROJECT_REPONAME:local . + # - run: + # name: Save docker image to workspace + # command: docker save -o /tmp/docker-image.tar mojaloop/$CIRCLE_PROJECT_REPONAME:local + # - persist_to_workspace: + # root: /tmp + # paths: + # - ./docker-image.tar - build-local-onboard-hub-accounts: - executor: default-machine - steps: - - checkout - - run: - name: Build Docker onboard-hub-accounts local image for testing - command: > - echo "Building Docker image: onboard-hub-accounts local" + # build-local-onboard-hub-accounts: + # executor: default-machine + # steps: + # - checkout + # - run: + # name: Build Docker onboard-hub-accounts local image for testing + # command: > + # echo "Building Docker image: onboard-hub-accounts local" - docker build - --build-arg CREATED="$(date -u --iso-8601=seconds)" - --build-arg VERSION="local" - --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - --build-arg REVISION="$CIRCLE_SHA1" - -t mojaloop/onboard-hub-accounts:local ./init/onboard-hub-accounts/ - - run: - name: Save docker image to workspace - command: docker save -o /tmp/docker-onboard-hub-accounts.tar mojaloop/onboard-hub-accounts:local - - persist_to_workspace: - root: /tmp - paths: - - ./docker-onboard-hub-accounts.tar + # docker build + # --build-arg CREATED="$(date -u --iso-8601=seconds)" + # --build-arg VERSION="local" + # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + # --build-arg REVISION="$CIRCLE_SHA1" + # -t mojaloop/onboard-hub-accounts:local ./init/onboard-hub-accounts/ + # - run: + # name: Save docker image to workspace + # command: docker save -o /tmp/docker-onboard-hub-accounts.tar mojaloop/onboard-hub-accounts:local + # - persist_to_workspace: + # root: /tmp + # paths: + # - ./docker-onboard-hub-accounts.tar - build-local-onboard-central-ledger: - executor: default-machine - steps: - - checkout - - run: - name: Build Docker onboard-central-ledger local image for testing - command: > - echo "Building Docker image: onboard-central-ledger local" + # build-local-onboard-central-ledger: + # executor: default-machine + # steps: + # - checkout + # - run: + # name: Build Docker onboard-central-ledger local image for testing + # command: > + # echo "Building Docker image: onboard-central-ledger local" - docker build - --build-arg CREATED="$(date -u --iso-8601=seconds)" - --build-arg VERSION="local" - --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - --build-arg REVISION="$CIRCLE_SHA1" - -t mojaloop/onboard-central-ledger:local ./init/onboard-central-ledger/ - - run: - name: Save docker image to workspace - command: docker save -o /tmp/docker-onboard-central-ledger.tar mojaloop/onboard-central-ledger:local - - persist_to_workspace: - root: /tmp - paths: - - ./docker-onboard-central-ledger.tar + # docker build + # --build-arg CREATED="$(date -u --iso-8601=seconds)" + # --build-arg VERSION="local" + # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + # --build-arg REVISION="$CIRCLE_SHA1" + # -t mojaloop/onboard-central-ledger:local ./init/onboard-central-ledger/ + # - run: + # name: Save docker image to workspace + # command: docker save -o /tmp/docker-onboard-central-ledger.tar mojaloop/onboard-central-ledger:local + # - persist_to_workspace: + # root: /tmp + # paths: + # - ./docker-onboard-central-ledger.tar - build-local-onboard-msisdn-oracle: - executor: default-machine - steps: - - checkout - - run: - name: Build Docker onboard-msisdn-oracle local image for testing - command: > - echo "Building Docker image: onboard-msisdn-oracle local" + # build-local-onboard-msisdn-oracle: + # executor: default-machine + # steps: + # - checkout + # - run: + # name: Build Docker onboard-msisdn-oracle local image for testing + # command: > + # echo "Building Docker image: onboard-msisdn-oracle local" - docker build - --build-arg CREATED="$(date -u --iso-8601=seconds)" - --build-arg VERSION="local" - --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - --build-arg REVISION="$CIRCLE_SHA1" - -t mojaloop/onboard-msisdn-oracle:local ./init/onboard-msisdn-oracle/ - - run: - name: Save docker image to workspace - command: docker save -o /tmp/docker-onboard-msisdn-oracle.tar mojaloop/onboard-msisdn-oracle:local - - persist_to_workspace: - root: /tmp - paths: - - ./docker-onboard-msisdn-oracle.tar + # docker build + # --build-arg CREATED="$(date -u --iso-8601=seconds)" + # --build-arg VERSION="local" + # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + # --build-arg REVISION="$CIRCLE_SHA1" + # -t mojaloop/onboard-msisdn-oracle:local ./init/onboard-msisdn-oracle/ + # - run: + # name: Save docker image to workspace + # command: docker save -o /tmp/docker-onboard-msisdn-oracle.tar mojaloop/onboard-msisdn-oracle:local + # - persist_to_workspace: + # root: /tmp + # paths: + # - ./docker-onboard-msisdn-oracle.tar license-scan: executor: default-machine @@ -671,187 +508,188 @@ jobs: - store_artifacts: path: anchore-reports - image-scan-onboard-hub-accounts: - executor: anchore/anchore_engine +# image-scan-onboard-hub-accounts: +# executor: anchore/anchore_engine +# steps: +# - setup_remote_docker +# - checkout +# - run: +# name: Install AWS CLI dependencies +# command: *defaults_awsCliDependencies +# - attach_workspace: +# at: /tmp +# - run: +# name: Load the pre-built docker image from workspace +# command: docker load -i /tmp/docker-onboard-hub-accounts.tar +# - anchore/analyze_local_image: +# dockerfile_path: ./Dockerfile +# image_name: mojaloop/onboard-hub-accounts:local +# # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below +# policy_failure: false +# timeout: '500' +# - run: +# name: Evaluate Failures. +# command: | +# if [[ ! $(which jq) ]]; then +# (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) +# fi +# if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then +# printf "\n%s\n" "The following OS packages are installed:" +# jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json +# fi +# if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then +# printf "\n%s\n" "The following vulnerabilities were found:" +# jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json +# fi +# # - run: +# # name: Upload Anchore reports to s3 +# # command: | +# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive +# # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" +# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive + +# # TODO: Enable this when we want to increase the strictness of our security policies +# # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) +# # echo "FailCount is: ${failCount}" +# # if [ $failCount -gt 0 ]; then +# # printf "Failed with a policy failure count of: ${failCount}" +# # exit 1 +# # fi +# - store_artifacts: +# path: anchore-reports + +# image-scan-onboard-central-ledger: +# executor: anchore/anchore_engine +# steps: +# - setup_remote_docker +# - checkout +# - run: +# name: Install AWS CLI dependencies +# command: *defaults_awsCliDependencies +# - attach_workspace: +# at: /tmp +# - run: +# name: Load the pre-built docker image from workspace +# command: docker load -i /tmp/docker-onboard-central-ledger.tar +# - anchore/analyze_local_image: +# dockerfile_path: ./Dockerfile +# image_name: mojaloop/onboard-central-ledger:local +# # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below +# policy_failure: false +# timeout: '500' +# - run: +# name: Evaluate Failures. +# command: | +# <<<<<<< HEAD +# aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive +# aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" +# aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive +# ======= +# if [[ ! $(which jq) ]]; then +# (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) +# fi +# if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then +# printf "\n%s\n" "The following OS packages are installed:" +# jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json +# fi +# if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then +# printf "\n%s\n" "The following vulnerabilities were found:" +# jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json +# fi +# # - run: +# # name: Upload Anchore reports to s3 +# # command: | +# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive +# # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" +# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive +# >>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee + +# # TODO: Enable this when we want to increase the strictness of our security policies +# # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) +# # echo "FailCount is: ${failCount}" +# # if [ $failCount -gt 0 ]; then +# # printf "Failed with a policy failure count of: ${failCount}" +# # exit 1 +# # fi +# - store_artifacts: +# path: anchore-reports + +# image-scan-onboard-msisdn-oracle: +# executor: anchore/anchore_engine +# steps: +# - setup_remote_docker +# - checkout +# - run: +# name: Install AWS CLI dependencies +# command: *defaults_awsCliDependencies +# - attach_workspace: +# at: /tmp +# - run: +# name: Load the pre-built docker image from workspace +# command: docker load -i /tmp/docker-onboard-msisdn-oracle.tar +# - anchore/analyze_local_image: +# dockerfile_path: ./Dockerfile +# image_name: mojaloop/onboard-msisdn-oracle:local +# # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below +# policy_failure: false +# timeout: '500' +# - run: +# name: Evaluate Failures. +# command: | +# if [[ ! $(which jq) ]]; then +# (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) +# fi +# if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then +# printf "\n%s\n" "The following OS packages are installed:" +# jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json +# fi +# if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then +# printf "\n%s\n" "The following vulnerabilities were found:" +# jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json +# fi +# # - run: +# # name: Upload Anchore reports to s3 +# # command: | +# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive +# # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" +# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive + +# # TODO: Enable this when we want to increase the strictness of our security policies +# # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) +# # echo "FailCount is: ${failCount}" +# # if [ $failCount -gt 0 ]; then +# # printf "Failed with a policy failure count of: ${failCount}" +# # exit 1 +# # fi +# - store_artifacts: +# path: anchore-reports + + publish: + executor: default-machine steps: - - setup_remote_docker - checkout - - run: - name: Install AWS CLI dependencies - command: *defaults_awsCliDependencies - attach_workspace: at: /tmp - run: name: Load the pre-built docker image from workspace - command: docker load -i /tmp/docker-onboard-hub-accounts.tar - - anchore/analyze_local_image: - dockerfile_path: ./Dockerfile - image_name: mojaloop/onboard-hub-accounts:local - # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below - policy_failure: false - timeout: '500' + command: docker load -i /tmp/docker-image.tar - run: - name: Evaluate Failures. - command: | - if [[ ! $(which jq) ]]; then - (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) - fi - if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then - printf "\n%s\n" "The following OS packages are installed:" - jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json - fi - if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then - printf "\n%s\n" "The following vulnerabilities were found:" - jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json - fi - # - run: - # name: Upload Anchore reports to s3 - # command: | - # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive - # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" - # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive - - # TODO: Enable this when we want to increase the strictness of our security policies - # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) - # echo "FailCount is: ${failCount}" - # if [ $failCount -gt 0 ]; then - # printf "Failed with a policy failure count of: ${failCount}" - # exit 1 - # fi - - store_artifacts: - path: anchore-reports - - image-scan-onboard-central-ledger: - executor: anchore/anchore_engine - steps: - - setup_remote_docker - - checkout + name: Login to Docker Hub + command: docker login -u $DOCKER_USER -p $DOCKER_PASS - run: - name: Install AWS CLI dependencies - command: *defaults_awsCliDependencies - - attach_workspace: - at: /tmp + name: Re-tag pre built image + command: | + docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - run: - name: Load the pre-built docker image from workspace - command: docker load -i /tmp/docker-onboard-central-ledger.tar - - anchore/analyze_local_image: - dockerfile_path: ./Dockerfile - image_name: mojaloop/onboard-central-ledger:local - # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below - policy_failure: false - timeout: '500' + name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub + # TODO: publish everything here + command: | + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG + echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG" + docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - run: - name: Evaluate Failures. - command: | -<<<<<<< HEAD - aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive - aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" - aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive -======= - if [[ ! $(which jq) ]]; then - (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) - fi - if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then - printf "\n%s\n" "The following OS packages are installed:" - jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json - fi - if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then - printf "\n%s\n" "The following vulnerabilities were found:" - jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json - fi - # - run: - # name: Upload Anchore reports to s3 - # command: | - # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive - # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" - # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - - # TODO: Enable this when we want to increase the strictness of our security policies - # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) - # echo "FailCount is: ${failCount}" - # if [ $failCount -gt 0 ]; then - # printf "Failed with a policy failure count of: ${failCount}" - # exit 1 - # fi - - store_artifacts: - path: anchore-reports - - image-scan-onboard-msisdn-oracle: - executor: anchore/anchore_engine - steps: - - setup_remote_docker - - checkout - - run: - name: Install AWS CLI dependencies - command: *defaults_awsCliDependencies - - attach_workspace: - at: /tmp - - run: - name: Load the pre-built docker image from workspace - command: docker load -i /tmp/docker-onboard-msisdn-oracle.tar - - anchore/analyze_local_image: - dockerfile_path: ./Dockerfile - image_name: mojaloop/onboard-msisdn-oracle:local - # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below - policy_failure: false - timeout: '500' - - run: - name: Evaluate Failures. - command: | - if [[ ! $(which jq) ]]; then - (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) - fi - if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then - printf "\n%s\n" "The following OS packages are installed:" - jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json - fi - if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then - printf "\n%s\n" "The following vulnerabilities were found:" - jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json - fi - # - run: - # name: Upload Anchore reports to s3 - # command: | - # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive - # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" - # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive - - # TODO: Enable this when we want to increase the strictness of our security policies - # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) - # echo "FailCount is: ${failCount}" - # if [ $failCount -gt 0 ]; then - # printf "Failed with a policy failure count of: ${failCount}" - # exit 1 - # fi - - store_artifacts: - path: anchore-reports - - publish: - executor: default-machine - steps: - - checkout - - attach_workspace: - at: /tmp - - run: - name: Load the pre-built docker image from workspace - command: docker load -i /tmp/docker-image.tar - - run: - name: Login to Docker Hub - command: docker login -u $DOCKER_USER -p $DOCKER_PASS - - run: - name: Re-tag pre built image - command: | - docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - - run: - name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub - command: | - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG - echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG" - docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - - run: - name: Slack announcement for tag releases + name: Slack announcement for tag releases command: | curl -X POST \ $SLACK_WEBHOOK_ANNOUNCEMENT \ @@ -859,145 +697,136 @@ jobs: -H 'cache-control: no-cache' \ -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - publish-onboard-hub-accounts: - executor: default-machine - steps: - - checkout - - attach_workspace: - at: /tmp - - run: - name: Load the pre-built docker image for onboard-hub-accounts from workspace - command: docker load -i /tmp/docker-onboard-hub-accounts.tar - - run: - name: Login to Docker Hub - command: docker login -u $DOCKER_USER -p $DOCKER_PASS - - run: - name: Setup environment vars for release/snapshot - command: ./.circleci/_set_up_deploy_envs.sh - - run: - name: Re-tag pre built image - command: | - docker tag $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG $DOCKER_ORG/onboard-hub-accounts:$RELEASE_TAG - - run: -<<<<<<< HEAD - <<: *defaults_build_docker_publish - - run: - <<: *defaults_slack_announcement +# publish-onboard-hub-accounts: +# executor: default-machine +# steps: +# - checkout +# - attach_workspace: +# at: /tmp +# - run: +# name: Load the pre-built docker image for onboard-hub-accounts from workspace +# command: docker load -i /tmp/docker-onboard-hub-accounts.tar +# - run: +# name: Login to Docker Hub +# command: docker login -u $DOCKER_USER -p $DOCKER_PASS +# - run: +# name: Setup environment vars for release/snapshot +# command: ./.circleci/_set_up_deploy_envs.sh +# - run: +# name: Re-tag pre built image +# command: | +# docker tag $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG $DOCKER_ORG/onboard-hub-accounts:$RELEASE_TAG +# - run: +# <<<<<<< HEAD +# <<: *defaults_build_docker_publish +# - run: +# <<: *defaults_slack_announcement - # deploy: - # executor: helm-kube - # steps: - # - checkout - # - run: - # name: Install AWS CLI dependencies - # command: *defaults_awsCliDependencies - # - run: - # name: setup environment vars for release/snapshot - # command: ./.circleci/_set_up_deploy_envs.sh - # - run: - # <<: *defaults_deploy_prequisites - # - run: - # <<: *defaults_deploy_config_kubernetes_cluster - # - run: - # <<: *defaults_deploy_config_kubernetes_credentials - # - run: - # <<: *defaults_deploy_config_kubernetes_context - # - run: - # <<: *defaults_deploy_set_kubernetes_context - # - run: - # <<: *defaults_deploy_configure_helm - # - run: - # <<: *defaults_deploy_install_or_upgrade_helm_chart +# # deploy: +# # executor: helm-kube +# # steps: +# # - checkout +# # - run: +# # name: Install AWS CLI dependencies +# # command: *defaults_awsCliDependencies +# # - run: +# # name: setup environment vars for release/snapshot +# # command: ./.circleci/_set_up_deploy_envs.sh +# # - run: +# # <<: *defaults_deploy_prequisites +# # - run: +# # <<: *defaults_deploy_config_kubernetes_cluster +# # - run: +# # <<: *defaults_deploy_config_kubernetes_credentials +# # - run: +# # <<: *defaults_deploy_config_kubernetes_context +# # - run: +# # <<: *defaults_deploy_set_kubernetes_context +# # - run: +# # <<: *defaults_deploy_configure_helm +# # - run: +# # <<: *defaults_deploy_install_or_upgrade_helm_chart -======= - name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-hub-accounts - command: | - echo "Publishing $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG" - docker push $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG - - run: - name: Slack announcement for tag releases - command: | - curl -X POST \ - $SLACK_WEBHOOK_ANNOUNCEMENT \ - -H 'Content-type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{\"text\": \"*onboard-hub-accounts* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" +# ======= +# name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-hub-accounts +# command: | +# echo "Publishing $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG" +# docker push $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG +# - run: +# name: Slack announcement for tag releases +# command: | +# curl -X POST \ +# $SLACK_WEBHOOK_ANNOUNCEMENT \ +# -H 'Content-type: application/json' \ +# -H 'cache-control: no-cache' \ +# -d "{\"text\": \"*onboard-hub-accounts* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - publish-onboard-central-ledger: - executor: default-machine - steps: - - checkout - - attach_workspace: - at: /tmp - - run: - name: Load the pre-built docker image for onboard-central-ledger from workspace - command: docker load -i /tmp/docker-onboard-central-ledger.tar - - run: - name: Login to Docker Hub - command: docker login -u $DOCKER_USER -p $DOCKER_PASS - - run: - name: Setup environment vars for release/snapshot - command: ./.circleci/_set_up_deploy_envs.sh - - run: - name: Re-tag pre built image - command: | - docker tag $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG $DOCKER_ORG/onboard-central-ledger:$RELEASE_TAG - - run: - name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-central-ledger - command: | - echo "Publishing $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG" - docker push $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG - - run: - name: Slack announcement for tag releases - command: | - curl -X POST \ - $SLACK_WEBHOOK_ANNOUNCEMENT \ - -H 'Content-type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{\"text\": \"*onboard-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" +# publish-onboard-central-ledger: +# executor: default-machine +# steps: +# - checkout +# - attach_workspace: +# at: /tmp +# - run: +# name: Load the pre-built docker image for onboard-central-ledger from workspace +# command: docker load -i /tmp/docker-onboard-central-ledger.tar +# - run: +# name: Login to Docker Hub +# command: docker login -u $DOCKER_USER -p $DOCKER_PASS +# - run: +# name: Setup environment vars for release/snapshot +# command: ./.circleci/_set_up_deploy_envs.sh +# - run: +# name: Re-tag pre built image +# command: | +# docker tag $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG $DOCKER_ORG/onboard-central-ledger:$RELEASE_TAG +# - run: +# name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-central-ledger +# command: | +# echo "Publishing $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG" +# docker push $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG +# - run: +# name: Slack announcement for tag releases +# command: | +# curl -X POST \ +# $SLACK_WEBHOOK_ANNOUNCEMENT \ +# -H 'Content-type: application/json' \ +# -H 'cache-control: no-cache' \ +# -d "{\"text\": \"*onboard-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - publish-onboard-msisdn-oracle: - executor: default-machine - steps: - - checkout - - attach_workspace: - at: /tmp - - run: - name: Load the pre-built docker image for onboard-msisdn-oracle from workspace - command: docker load -i /tmp/docker-onboard-msisdn-oracle.tar - - run: - name: Login to Docker Hub - command: docker login -u $DOCKER_USER -p $DOCKER_PASS - - run: - name: Setup environment vars for release/snapshot - command: ./.circleci/_set_up_deploy_envs.sh - - run: - name: Re-tag pre built image - command: | - docker tag $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG $DOCKER_ORG/onboard-msisdn-oracle:$RELEASE_TAG - - run: - name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-msisdn-oracle - command: | - echo "Publishing $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG" - docker push $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG - - run: - name: Slack announcement for tag releases - command: | - curl -X POST \ - $SLACK_WEBHOOK_ANNOUNCEMENT \ - -H 'Content-type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{\"text\": \"*onboard-msisdn-oracle* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" +# publish-onboard-msisdn-oracle: +# executor: default-machine +# steps: +# - checkout +# - attach_workspace: +# at: /tmp +# - run: +# name: Load the pre-built docker image for onboard-msisdn-oracle from workspace +# command: docker load -i /tmp/docker-onboard-msisdn-oracle.tar +# - run: +# name: Login to Docker Hub +# command: docker login -u $DOCKER_USER -p $DOCKER_PASS +# - run: +# name: Setup environment vars for release/snapshot +# command: ./.circleci/_set_up_deploy_envs.sh +# - run: +# name: Re-tag pre built image +# command: | +# docker tag $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG $DOCKER_ORG/onboard-msisdn-oracle:$RELEASE_TAG +# - run: +# name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-msisdn-oracle +# command: | +# echo "Publishing $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG" +# docker push $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG +# - run: +# name: Slack announcement for tag releases +# command: | +# curl -X POST \ +# $SLACK_WEBHOOK_ANNOUNCEMENT \ +# -H 'Content-type: application/json' \ +# -H 'cache-control: no-cache' \ +# -d "{\"text\": \"*onboard-msisdn-oracle* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - deploy: - executor: deploy-kube/helm-kube - steps: - - checkout - - deploy-kube/setup_and_run: - helm_set_values: | - --set finance-portal.frontend.image.repository=$DOCKER_ORG/$CIRCLE_PROJECT_REPONAME \ - --set finance-portal.frontend.image.tag=$CIRCLE_TAG ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee ## # Workflows @@ -1050,26 +879,6 @@ workflows: - /feature*/ - /bugfix*/ - /hotfix*/ - - vulnerability-check-onboard-hub-accounts: - context: org-global - requires: - - setup - filters: - branches: - ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ - - vulnerability-check-onboard-central-ledger: - context: org-global - requires: - - setup - filters: - branches: - ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ - audit-licenses: context: org-global requires: @@ -1090,36 +899,36 @@ workflows: - /feature*/ - /bugfix*/ - /hotfix*/ - - build-local-onboard-hub-accounts: - context: org-global - requires: - - setup - filters: - branches: - ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ - - build-local-onboard-central-ledger: - context: org-global - requires: - - setup - filters: - branches: - ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ - - build-local-onboard-msisdn-oracle: - context: org-global - requires: - - setup - filters: - branches: - ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ + # - build-local-onboard-hub-accounts: + # context: org-global + # requires: + # - setup + # filters: + # branches: + # ignore: + # - /feature*/ + # - /bugfix*/ + # - /hotfix*/ + # - build-local-onboard-central-ledger: + # context: org-global + # requires: + # - setup + # filters: + # branches: + # ignore: + # - /feature*/ + # - /bugfix*/ + # - /hotfix*/ + # - build-local-onboard-msisdn-oracle: + # context: org-global + # requires: + # - setup + # filters: + # branches: + # ignore: + # - /feature*/ + # - /bugfix*/ + # - /hotfix*/ - license-scan: context: org-global requires: @@ -1140,140 +949,76 @@ workflows: - /feature*/ - /bugfix*/ - /hotfix*/ - - image-scan-onboard-hub-accounts: - context: org-global - requires: - - build-local-onboard-hub-accounts - filters: - branches: - ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ - - image-scan-onboard-central-ledger: - context: org-global - requires: - - build-local-onboard-central-ledger - filters: - branches: - ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ - - image-scan-onboard-msisdn-oracle: - context: org-global - requires: - - build-local-onboard-msisdn-oracle - filters: - branches: - ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ - - build: - context: org-global - requires: - - setup - filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)?/ - branches: - ignore: - - /.*/ - - build-onboard-hub-accounts: - context: org-global - requires: - - setup - filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ - branches: - ignore: - - /.*/ - - build-onboard-central-ledger: + # - image-scan-onboard-hub-accounts: + # context: org-global + # requires: + # - build-local-onboard-hub-accounts + # filters: + # branches: + # ignore: + # - /feature*/ + # - /bugfix*/ + # - /hotfix*/ + # - image-scan-onboard-central-ledger: + # context: org-global + # requires: + # - build-local-onboard-central-ledger + # filters: + # branches: + # ignore: + # - /feature*/ + # - /bugfix*/ + # - /hotfix*/ + # - image-scan-onboard-msisdn-oracle: + # context: org-global + # requires: + # - build-local-onboard-msisdn-oracle + # filters: + # branches: + # ignore: + # - /feature*/ + # - /bugfix*/ + # - /hotfix*/ + # New commits to master release automatically + - release: context: org-global requires: - - setup + - pr-tools/pr-title-check + - test-unit + - test-coverage + - vulnerability-check + - audit-licenses + - test-integration + - license-scan + - image-scan filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: - ignore: - - /.*/ - - build-onboard-msisdn-oracle: + only: + - master + - /release\/v.*/ + - github-release: context: org-global requires: - - setup + - release filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: - ignore: - - /.*/ + only: + - master + - /release\/v.*/ - publish: context: org-global requires: - - build - - build-onboard-central-ledger - - build-onboard-msisdn-oracle + - pr-tools/pr-title-check + - test-unit + - test-coverage + - vulnerability-check + - audit-licenses + - test-integration + - license-scan + - image-scan filters: tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)?/ - branches: - ignore: - - /.*/ - - publish-onboard-hub-accounts: - context: org-global - requires: - - build - - build-onboard-central-ledger - - build-onboard-msisdn-oracle - - build-onboard-hub-accounts - filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)?/ - branches: - ignore: - - /.*/ - - publish-onboard-central-ledger: - context: org-global - requires: - - build - - build-onboard-central-ledger - - build-onboard-msisdn-oracle - - build-onboard-hub-accounts - filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?(\-pisp)?/ - branches: - ignore: - - /.*/ -<<<<<<< HEAD -======= - - publish-onboard-msisdn-oracle: - context: org-global - requires: - - build - - build-onboard-central-ledger - - build-onboard-msisdn-oracle - - build-onboard-hub-accounts - filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ - branches: - ignore: - - /.*/ - - deploy: - context: org-global - requires: - - publish - - publish-onboard-central-ledger - - publish-onboard-msisdn-oracle - - publish-onboard-hub-accounts - filters: - tags: - only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?/ + only: /.*/ branches: ignore: - - /.*/ ->>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee + - /.*/ \ No newline at end of file diff --git a/src/package.json b/src/package.json index 297fa32e..f3202d35 100644 --- a/src/package.json +++ b/src/package.json @@ -1,7 +1,7 @@ { "name": "mojaloop-simulator", "version": "11.4.3", - "description": "A canonical test example implementation of the parties, transfers and quotes resources of the Mojaloop API", + "description": "A canonical test example implementation of the parties, transfers and quotes resources of the Mojaloop API", "license": "Apache-2.0", "main": "index.js", "author": "Matt Kingston, ModusBox Inc.", @@ -51,7 +51,8 @@ "dep:check:lib-validate": "npx ncu -e 2 --packageFile ./lib/validate/package.json", "dep:update:lib-validate": "npx ncu -u --packageFile ./lib/validate/package.json", "dep:check:all": "run-s -c dep:check:lib-validate dep:check:lib-rules-engine dep:check:lib-router dep:check:lib-randomphrase dep:check:lib-log dep:check", - "dep:update:all": "run-s -c dep:update:lib-validate dep:update:lib-rules-engine dep:update:lib-router dep:update:lib-randomphrase dep:update:lib-log dep:update" + "dep:update:all": "run-s -c dep:update:lib-validate dep:update:lib-rules-engine dep:update:lib-router dep:update:lib-randomphrase dep:update:lib-log dep:update", + "release": "standard-version --releaseCommitMessageFormat 'chore(release): {{currentTag}} [skip ci]'" }, "dependencies": { "@internal/log": "file:lib/log", @@ -84,6 +85,7 @@ "npm-check-updates": "11.6.0", "npm-run-all": "4.1.5", "nyc": "15.1.0", + "standard-version": "^9.3.1", "tap-xunit": "2.4.1", "uuid": "8.3.2" }, From 960133415cb1e9fda79cdafc617ef5710a5bba8f Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 16:58:56 +0930 Subject: [PATCH 27/34] feat: tidy up circleci config, add autoreleases --- .circleci/config.yml | 737 +++++++++---------------------------------- 1 file changed, 143 insertions(+), 594 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d6e715ed..61bb045d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,25 +13,24 @@ version: 2.1 ## orbs: anchore: anchore/anchore-engine@1.6.0 - deploy-kube: mojaloop/deployment@0.1.6 + slack: circleci/slack@3.4.2 pr-tools: mojaloop/pr-tools@0.1.8 + github-release: h-matsuo/github-release@0.1.3 -# TODO: Further evaluate what changes need to be pulled from master. -# File has not been updated to v11.3.0 ## # defaults # # YAML defaults templates, in alphabetical order ## defaults_Dependencies: &defaults_Dependencies | - apk --update --no-cache add \ - git \ - ca-certificates \ - curl \ - openssh-client \ - -t build-dependencies make gcc g++ python3 libtool autoconf automake - npm config set unsafe-perm true - npm install -g node-gyp + apk --no-cache add git + apk --no-cache add ca-certificates + apk --no-cache add curl + apk --no-cache add openssh-client + apk add --no-cache -t build-dependencies make gcc g++ python libtool autoconf automake jq + npm config set unsafe-perm true + npm install -g node-gyp + defaults_awsCliDependencies: &defaults_awsCliDependencies | apk --update --no-cache add \ @@ -171,6 +170,11 @@ jobs: - run: name: Install general dependencies command: *defaults_Dependencies + - run: + name: Check for vulns in ./init by installing first + command: > + cd init/onboard-hub-accounts && npm ci + cd init/onboard-central-ledger && npm ci - run: name: Create dir for test results command: mkdir -p ./audit/results @@ -181,7 +185,7 @@ jobs: path: ./audit/results prefix: audit - vulnerability-check-onboard-hub-accounts: + audit-licenses: executor: default-docker steps: - checkout @@ -195,21 +199,20 @@ jobs: name: Install general dependencies command: *defaults_Dependencies - run: - name: Update NPM install (using `npm ci`) - command: cd init/onboard-hub-accounts && npm ci - - run: - name: Create dir for test results - command: mkdir -p ./audit/results + <<: *defaults_license_scanner - run: - name: Check for new npm vulnerabilities - command: cd src && npm run audit:check --silent -- --json > ../audit/results/auditResults.json + name: Run the license-scanner + command: cd /tmp/license-scanner && pathToRepo=$CIRCLE_WORKING_DIRECTORY make run - store_artifacts: - path: ./audit/results - prefix: audit + path: /tmp/license-scanner/results + prefix: licenses - vulnerability-check-onboard-central-ledger: + release: executor: default-docker steps: + - run: + name: Install general dependencies + command: *defaults_Dependencies - checkout - restore_cache: key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} @@ -218,48 +221,65 @@ jobs: - src/lib/log/node_modules - src/lib/validate/node_modules - run: - name: Install general dependencies - command: *defaults_Dependencies + name: Configure git + command: | + git config user.email ${GIT_CI_EMAIL} + git config user.name ${GIT_CI_USER} + git checkout ${CIRCLE_BRANCH} - run: - name: Update NPM install (using `npm ci`) - command: cd init/onboard-central-ledger && npm ci + name: Configure ssh + command: | + mkdir -p ~/.ssh + ssh-keyscan -p 443 ssh.github.com >> ~/.ssh/known_hosts + ssh-keyscan github.com >> ~/.ssh/known_hosts - run: - name: Create dir for test results - command: mkdir -p ./audit/results + name: Generate changelog and bump package version + command: cd src && npm run release - run: - name: Check for new npm vulnerabilities - command: cd src && npm run audit:check --silent -- --json > ../audit/results/auditResults.json - - store_artifacts: - path: ./audit/results - prefix: audit + name: Push the release + command: git push --follow-tags origin ${CIRCLE_BRANCH} - audit-licenses: - executor: default-docker + github-release: + executor: default-machine steps: + - run: + name: Install git + command: | + sudo apt-get update && sudo apt-get install -y git - checkout - - restore_cache: - key: dependency-cache-v1-{{ checksum "src/package-lock.json" }} - paths: - - src/node_modules - - src/lib/log/node_modules - - src/lib/validate/node_modules - run: - name: Install general dependencies - command: *defaults_Dependencies + name: Fetch updated release branch + command: | + git config user.email ${GIT_CI_EMAIL} + git config user.name ${GIT_CI_USER} + git fetch origin + git checkout origin/${CIRCLE_BRANCH} - run: - <<: *defaults_license_scanner + # Note: this is rather imperfect, but will do for now + name: Format the changelog into the github release body and get release tag + command: | + git diff --no-indent-heuristic master~1 HEAD CHANGELOG.md | sed -n '/^+[^+]/ s/^+//p' > /tmp/changes + echo 'export RELEASE_CHANGES=`cat /tmp/changes`' >> $BASH_ENV + echo 'export RELEASE_TAG=`cat src/package-lock.json | jq -r .version`' >> $BASH_ENV - run: - name: Run the license-scanner - command: cd /tmp/license-scanner && pathToRepo=$CIRCLE_WORKING_DIRECTORY make run - - store_artifacts: - path: /tmp/license-scanner/results - prefix: licenses + name: check the release changes + command: | + echo "Changes are: ${RELEASE_CHANGES}" + - github-release/create: + github-token-variable: ${GITHUB_TOKEN} + tag: v${RELEASE_TAG} + title: v${RELEASE_TAG} Release + description: ${RELEASE_CHANGES} + file-path: CHANGELOG.md + - slack/status: + webhook: "$SLACK_WEBHOOK_ANNOUNCEMENT" + success_message: '*"${CIRCLE_PROJECT_REPONAME}"* - Release \`"v${RELEASE_TAG}"\` \nhttps://github.com/mojaloop/"${CIRCLE_PROJECT_REPONAME}"/releases/tag/"v${RELEASE_TAG}"' + build: executor: default-machine steps: - checkout - # TODO: build all the images here! - run: name: Build Docker $CIRCLE_TAG image command: > @@ -274,171 +294,55 @@ jobs: - run: name: Save docker image to workspace command: docker save -o /tmp/docker-image.tar $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG + - run: + name: Build Docker onboard-hub-accounts $CIRCLE_TAG image + command: > + echo "Building Docker image: onboard-hub-accounts $CIRCLE_TAG" + + docker build + --build-arg CREATED="$(date -u --iso-8601=seconds)" + --build-arg VERSION="$RELEASE_TAG" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" + -t $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG ./init/onboard-hub-accounts/ + - run: + name: Save docker image to workspace + command: docker save -o /tmp/docker-onboard-hub-accounts.tar $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG + - run: + name: Build Docker onboard-msisdn-oracle $CIRCLE_TAG image + command: > + echo "Building Docker image: onboard-msisdn-oracle $CIRCLE_TAG" + + docker build + --build-arg CREATED="$(date -u --iso-8601=seconds)" + --build-arg VERSION="$RELEASE_TAG" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" + -t $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG ./init/onboard-msisdn-oracle/ + - run: + name: Save docker image to workspace + command: docker save -o /tmp/docker-onboard-msisdn-oracle.tar $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG + - run: + name: Build Docker onboard-central-ledger $CIRCLE_TAG image + command: > + echo "Building Docker image: onboard-central-ledger $CIRCLE_TAG" + + docker build + --build-arg CREATED="$(date -u --iso-8601=seconds)" + --build-arg VERSION="$RELEASE_TAG" + --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" + --build-arg REVISION="$CIRCLE_SHA1" + -t $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG ./init/onboard-central-ledger/ + - run: + name: Save docker image to workspace + command: docker save -o /tmp/docker-onboard-central-ledger.tar $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG - persist_to_workspace: root: /tmp paths: - ./docker-image.tar - - # build-onboard-hub-accounts: - # executor: default-machine - # steps: - # - checkout - # - run: - # name: Build Docker onboard-hub-accounts $CIRCLE_TAG image - # command: > - # echo "Building Docker image: onboard-hub-accounts $CIRCLE_TAG" - - # docker build - # --build-arg CREATED="$(date -u --iso-8601=seconds)" - # --build-arg VERSION="$RELEASE_TAG" - # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - # --build-arg REVISION="$CIRCLE_SHA1" - # -t $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG ./init/onboard-hub-accounts/ - # - run: - # name: Save docker image to workspace - # command: docker save -o /tmp/docker-onboard-hub-accounts.tar $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG - # - persist_to_workspace: - # root: /tmp - # paths: - # - ./docker-onboard-hub-accounts.tar - - # build-onboard-central-ledger: - # executor: default-machine - # steps: - # - checkout - # - run: - # name: Build Docker onboard-central-ledger $CIRCLE_TAG image - # command: > - # echo "Building Docker image: onboard-central-ledger $CIRCLE_TAG" - - # docker build - # --build-arg CREATED="$(date -u --iso-8601=seconds)" - # --build-arg VERSION="$RELEASE_TAG" - # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - # --build-arg REVISION="$CIRCLE_SHA1" - # -t $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG ./init/onboard-central-ledger/ - # - run: - # name: Save docker image to workspace - # command: docker save -o /tmp/docker-onboard-central-ledger.tar $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG - # - persist_to_workspace: - # root: /tmp - # paths: - # - ./docker-onboard-central-ledger.tar - - # build-onboard-msisdn-oracle: - # executor: default-machine - # steps: - # - checkout - # - run: - # name: Build Docker onboard-msisdn-oracle $CIRCLE_TAG image - # command: > - # echo "Building Docker image: onboard-msisdn-oracle $CIRCLE_TAG" - - # docker build - # --build-arg CREATED="$(date -u --iso-8601=seconds)" - # --build-arg VERSION="$RELEASE_TAG" - # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - # --build-arg REVISION="$CIRCLE_SHA1" - # -t $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG ./init/onboard-msisdn-oracle/ - # - run: - # name: Save docker image to workspace - # command: docker save -o /tmp/docker-onboard-msisdn-oracle.tar $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG - # - persist_to_workspace: - # root: /tmp - # paths: - # - ./docker-onboard-msisdn-oracle.tar - - # build-local: - # executor: default-machine - # steps: - # - checkout - # - run: - # name: Build Docker local image for testing - # command: > - # echo "Building Docker image: local" - - # docker build - # --build-arg CREATED="$(date -u --iso-8601=seconds)" - # --build-arg VERSION="local" - # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - # --build-arg REVISION="$CIRCLE_SHA1" - # -t mojaloop/$CIRCLE_PROJECT_REPONAME:local . - # - run: - # name: Save docker image to workspace - # command: docker save -o /tmp/docker-image.tar mojaloop/$CIRCLE_PROJECT_REPONAME:local - # - persist_to_workspace: - # root: /tmp - # paths: - # - ./docker-image.tar - - # build-local-onboard-hub-accounts: - # executor: default-machine - # steps: - # - checkout - # - run: - # name: Build Docker onboard-hub-accounts local image for testing - # command: > - # echo "Building Docker image: onboard-hub-accounts local" - - # docker build - # --build-arg CREATED="$(date -u --iso-8601=seconds)" - # --build-arg VERSION="local" - # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - # --build-arg REVISION="$CIRCLE_SHA1" - # -t mojaloop/onboard-hub-accounts:local ./init/onboard-hub-accounts/ - # - run: - # name: Save docker image to workspace - # command: docker save -o /tmp/docker-onboard-hub-accounts.tar mojaloop/onboard-hub-accounts:local - # - persist_to_workspace: - # root: /tmp - # paths: - # - ./docker-onboard-hub-accounts.tar - - # build-local-onboard-central-ledger: - # executor: default-machine - # steps: - # - checkout - # - run: - # name: Build Docker onboard-central-ledger local image for testing - # command: > - # echo "Building Docker image: onboard-central-ledger local" - - # docker build - # --build-arg CREATED="$(date -u --iso-8601=seconds)" - # --build-arg VERSION="local" - # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - # --build-arg REVISION="$CIRCLE_SHA1" - # -t mojaloop/onboard-central-ledger:local ./init/onboard-central-ledger/ - # - run: - # name: Save docker image to workspace - # command: docker save -o /tmp/docker-onboard-central-ledger.tar mojaloop/onboard-central-ledger:local - # - persist_to_workspace: - # root: /tmp - # paths: - # - ./docker-onboard-central-ledger.tar - - # build-local-onboard-msisdn-oracle: - # executor: default-machine - # steps: - # - checkout - # - run: - # name: Build Docker onboard-msisdn-oracle local image for testing - # command: > - # echo "Building Docker image: onboard-msisdn-oracle local" - - # docker build - # --build-arg CREATED="$(date -u --iso-8601=seconds)" - # --build-arg VERSION="local" - # --build-arg SOURCE="$CIRCLE_REPOSITORY_URL" - # --build-arg REVISION="$CIRCLE_SHA1" - # -t mojaloop/onboard-msisdn-oracle:local ./init/onboard-msisdn-oracle/ - # - run: - # name: Save docker image to workspace - # command: docker save -o /tmp/docker-onboard-msisdn-oracle.tar mojaloop/onboard-msisdn-oracle:local - # - persist_to_workspace: - # root: /tmp - # paths: - # - ./docker-onboard-msisdn-oracle.tar + - ./docker-onboard-hub-accounts.tar + - ./docker-onboard-msisdn-oracle.tar + - ./docker-onboard-central-ledger.tar license-scan: executor: default-machine @@ -491,179 +395,9 @@ jobs: printf "\n%s\n" "The following vulnerabilities were found:" jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json fi -# - run: -# name: Upload Anchore reports to s3 -# command: | -# aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive -# aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" -# aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive - - # TODO: Enable this when we want to increase the strictness of our security policies - # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) - # echo "FailCount is: ${failCount}" - # if [ $failCount -gt 0 ]; then - # printf "Failed with a policy failure count of: ${failCount}" - # exit 1 - # fi - store_artifacts: path: anchore-reports - -# image-scan-onboard-hub-accounts: -# executor: anchore/anchore_engine -# steps: -# - setup_remote_docker -# - checkout -# - run: -# name: Install AWS CLI dependencies -# command: *defaults_awsCliDependencies -# - attach_workspace: -# at: /tmp -# - run: -# name: Load the pre-built docker image from workspace -# command: docker load -i /tmp/docker-onboard-hub-accounts.tar -# - anchore/analyze_local_image: -# dockerfile_path: ./Dockerfile -# image_name: mojaloop/onboard-hub-accounts:local -# # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below -# policy_failure: false -# timeout: '500' -# - run: -# name: Evaluate Failures. -# command: | -# if [[ ! $(which jq) ]]; then -# (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) -# fi -# if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then -# printf "\n%s\n" "The following OS packages are installed:" -# jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json -# fi -# if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then -# printf "\n%s\n" "The following vulnerabilities were found:" -# jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json -# fi -# # - run: -# # name: Upload Anchore reports to s3 -# # command: | -# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive -# # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" -# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive - -# # TODO: Enable this when we want to increase the strictness of our security policies -# # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) -# # echo "FailCount is: ${failCount}" -# # if [ $failCount -gt 0 ]; then -# # printf "Failed with a policy failure count of: ${failCount}" -# # exit 1 -# # fi -# - store_artifacts: -# path: anchore-reports - -# image-scan-onboard-central-ledger: -# executor: anchore/anchore_engine -# steps: -# - setup_remote_docker -# - checkout -# - run: -# name: Install AWS CLI dependencies -# command: *defaults_awsCliDependencies -# - attach_workspace: -# at: /tmp -# - run: -# name: Load the pre-built docker image from workspace -# command: docker load -i /tmp/docker-onboard-central-ledger.tar -# - anchore/analyze_local_image: -# dockerfile_path: ./Dockerfile -# image_name: mojaloop/onboard-central-ledger:local -# # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below -# policy_failure: false -# timeout: '500' -# - run: -# name: Evaluate Failures. -# command: | -# <<<<<<< HEAD -# aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive -# aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" -# aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive -# ======= -# if [[ ! $(which jq) ]]; then -# (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) -# fi -# if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then -# printf "\n%s\n" "The following OS packages are installed:" -# jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json -# fi -# if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then -# printf "\n%s\n" "The following vulnerabilities were found:" -# jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json -# fi -# # - run: -# # name: Upload Anchore reports to s3 -# # command: | -# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive -# # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" -# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive -# >>>>>>> d5e777dae5b0bfada24f999bc9851d0ebdb6abee - -# # TODO: Enable this when we want to increase the strictness of our security policies -# # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) -# # echo "FailCount is: ${failCount}" -# # if [ $failCount -gt 0 ]; then -# # printf "Failed with a policy failure count of: ${failCount}" -# # exit 1 -# # fi -# - store_artifacts: -# path: anchore-reports - -# image-scan-onboard-msisdn-oracle: -# executor: anchore/anchore_engine -# steps: -# - setup_remote_docker -# - checkout -# - run: -# name: Install AWS CLI dependencies -# command: *defaults_awsCliDependencies -# - attach_workspace: -# at: /tmp -# - run: -# name: Load the pre-built docker image from workspace -# command: docker load -i /tmp/docker-onboard-msisdn-oracle.tar -# - anchore/analyze_local_image: -# dockerfile_path: ./Dockerfile -# image_name: mojaloop/onboard-msisdn-oracle:local -# # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below -# policy_failure: false -# timeout: '500' -# - run: -# name: Evaluate Failures. -# command: | -# if [[ ! $(which jq) ]]; then -# (set +o pipefail; apk add jq || apt-get install -y jq || yum install -y jq) -# fi -# if [[ $(ls anchore-reports/*content-os*.json 2> /dev/null) ]]; then -# printf "\n%s\n" "The following OS packages are installed:" -# jq '[.content | sort_by(.package) | .[] | {package: .package, version: .version}]' anchore-reports/*content-os*.json -# fi -# if [[ $(ls anchore-reports/*vuln*.json 2> /dev/null) ]]; then -# printf "\n%s\n" "The following vulnerabilities were found:" -# jq '[.vulnerabilities | group_by(.package) | .[] | {package: .[0].package, vuln: [.[].vuln]}]' anchore-reports/*vuln*.json -# fi -# # - run: -# # name: Upload Anchore reports to s3 -# # command: | -# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/${CIRCLE_PROJECT_REPONAME}/ --recursive -# # aws s3 rm ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive --exclude "*" --include "${CIRCLE_PROJECT_REPONAME}*" -# # aws s3 cp anchore-reports ${AWS_S3_DIR_ANCHORE_REPORTS}/latest/ --recursive - -# # TODO: Enable this when we want to increase the strictness of our security policies -# # failCount=$(cat anchore-reports/*policy*.json | grep 'fail' | wc -l) -# # echo "FailCount is: ${failCount}" -# # if [ $failCount -gt 0 ]; then -# # printf "Failed with a policy failure count of: ${failCount}" -# # exit 1 -# # fi -# - store_artifacts: -# path: anchore-reports - + publish: executor: default-machine steps: @@ -671,8 +405,12 @@ jobs: - attach_workspace: at: /tmp - run: - name: Load the pre-built docker image from workspace - command: docker load -i /tmp/docker-image.tar + name: Load the pre-built docker images from workspace + command: > + docker load -i /tmp/docker-image.tar + docker load -i /tmp/docker-onboard-hub-accounts.tar + docker load -i /tmp/docker-onboard-msisdn-oracle.tar + docker load -i /tmp/docker-onboard-central-ledger.tar - run: name: Login to Docker Hub command: docker login -u $DOCKER_USER -p $DOCKER_PASS @@ -682,151 +420,19 @@ jobs: docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - run: name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub - # TODO: publish everything here command: | echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG" docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG echo "Publishing $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG" docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - - run: - name: Slack announcement for tag releases - command: | - curl -X POST \ - $SLACK_WEBHOOK_ANNOUNCEMENT \ - -H 'Content-type: application/json' \ - -H 'cache-control: no-cache' \ - -d "{\"text\": \"*${CIRCLE_PROJECT_REPONAME}* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - -# publish-onboard-hub-accounts: -# executor: default-machine -# steps: -# - checkout -# - attach_workspace: -# at: /tmp -# - run: -# name: Load the pre-built docker image for onboard-hub-accounts from workspace -# command: docker load -i /tmp/docker-onboard-hub-accounts.tar -# - run: -# name: Login to Docker Hub -# command: docker login -u $DOCKER_USER -p $DOCKER_PASS -# - run: -# name: Setup environment vars for release/snapshot -# command: ./.circleci/_set_up_deploy_envs.sh -# - run: -# name: Re-tag pre built image -# command: | -# docker tag $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG $DOCKER_ORG/onboard-hub-accounts:$RELEASE_TAG -# - run: -# <<<<<<< HEAD -# <<: *defaults_build_docker_publish -# - run: -# <<: *defaults_slack_announcement - -# # deploy: -# # executor: helm-kube -# # steps: -# # - checkout -# # - run: -# # name: Install AWS CLI dependencies -# # command: *defaults_awsCliDependencies -# # - run: -# # name: setup environment vars for release/snapshot -# # command: ./.circleci/_set_up_deploy_envs.sh -# # - run: -# # <<: *defaults_deploy_prequisites -# # - run: -# # <<: *defaults_deploy_config_kubernetes_cluster -# # - run: -# # <<: *defaults_deploy_config_kubernetes_credentials -# # - run: -# # <<: *defaults_deploy_config_kubernetes_context -# # - run: -# # <<: *defaults_deploy_set_kubernetes_context -# # - run: -# # <<: *defaults_deploy_configure_helm -# # - run: -# # <<: *defaults_deploy_install_or_upgrade_helm_chart - -# ======= -# name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-hub-accounts -# command: | -# echo "Publishing $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG" -# docker push $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG -# - run: -# name: Slack announcement for tag releases -# command: | -# curl -X POST \ -# $SLACK_WEBHOOK_ANNOUNCEMENT \ -# -H 'Content-type: application/json' \ -# -H 'cache-control: no-cache' \ -# -d "{\"text\": \"*onboard-hub-accounts* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - -# publish-onboard-central-ledger: -# executor: default-machine -# steps: -# - checkout -# - attach_workspace: -# at: /tmp -# - run: -# name: Load the pre-built docker image for onboard-central-ledger from workspace -# command: docker load -i /tmp/docker-onboard-central-ledger.tar -# - run: -# name: Login to Docker Hub -# command: docker login -u $DOCKER_USER -p $DOCKER_PASS -# - run: -# name: Setup environment vars for release/snapshot -# command: ./.circleci/_set_up_deploy_envs.sh -# - run: -# name: Re-tag pre built image -# command: | -# docker tag $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG $DOCKER_ORG/onboard-central-ledger:$RELEASE_TAG -# - run: -# name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-central-ledger -# command: | -# echo "Publishing $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG" -# docker push $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG -# - run: -# name: Slack announcement for tag releases -# command: | -# curl -X POST \ -# $SLACK_WEBHOOK_ANNOUNCEMENT \ -# -H 'Content-type: application/json' \ -# -H 'cache-control: no-cache' \ -# -d "{\"text\": \"*onboard-central-ledger* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" - -# publish-onboard-msisdn-oracle: -# executor: default-machine -# steps: -# - checkout -# - attach_workspace: -# at: /tmp -# - run: -# name: Load the pre-built docker image for onboard-msisdn-oracle from workspace -# command: docker load -i /tmp/docker-onboard-msisdn-oracle.tar -# - run: -# name: Login to Docker Hub -# command: docker login -u $DOCKER_USER -p $DOCKER_PASS -# - run: -# name: Setup environment vars for release/snapshot -# command: ./.circleci/_set_up_deploy_envs.sh -# - run: -# name: Re-tag pre built image -# command: | -# docker tag $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG $DOCKER_ORG/onboard-msisdn-oracle:$RELEASE_TAG -# - run: -# name: Publish Docker image $CIRCLE_TAG & Latest tag to Docker Hub for onboard-msisdn-oracle -# command: | -# echo "Publishing $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG" -# docker push $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG -# - run: -# name: Slack announcement for tag releases -# command: | -# curl -X POST \ -# $SLACK_WEBHOOK_ANNOUNCEMENT \ -# -H 'Content-type: application/json' \ -# -H 'cache-control: no-cache' \ -# -d "{\"text\": \"*onboard-msisdn-oracle* - Release \`${CIRCLE_TAG}\`: https://github.com/mojaloop/${CIRCLE_PROJECT_REPONAME}/releases/tag/${CIRCLE_TAG}\"}" + # publish init images + docker push $DOCKER_ORG/onboard-hub-accounts:$RELEASE_TAG + docker push $DOCKER_ORG/onboard-msisdn-oracle:$RELEASE_TAG + docker push $DOCKER_ORG/onboard-central-ledger:$RELEASE_TAG + - slack/status: + webhook: "$SLACK_WEBHOOK_ANNOUNCEMENT" + success_message: '*"${CIRCLE_PROJECT_REPONAME}"* - Release \`"${CIRCLE_TAG}"\` \nhttps://github.com/mojaloop/"${CIRCLE_PROJECT_REPONAME}"/releases/tag/"${CIRCLE_TAG}"' ## # Workflows @@ -889,96 +495,41 @@ workflows: - /feature*/ - /bugfix*/ - /hotfix*/ - - build-local: + - build: context: org-global requires: - setup + - test-unit + - test-coverage + - vulnerability-check + - audit-licenses filters: branches: ignore: - /feature*/ - /bugfix*/ - /hotfix*/ - # - build-local-onboard-hub-accounts: - # context: org-global - # requires: - # - setup - # filters: - # branches: - # ignore: - # - /feature*/ - # - /bugfix*/ - # - /hotfix*/ - # - build-local-onboard-central-ledger: - # context: org-global - # requires: - # - setup - # filters: - # branches: - # ignore: - # - /feature*/ - # - /bugfix*/ - # - /hotfix*/ - # - build-local-onboard-msisdn-oracle: - # context: org-global - # requires: - # - setup - # filters: - # branches: - # ignore: - # - /feature*/ - # - /bugfix*/ - # - /hotfix*/ - license-scan: context: org-global requires: - - build-local + - build filters: + tags: + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ + - /.*/ - image-scan: context: org-global requires: - - build-local + - build filters: + tags: + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ - # - image-scan-onboard-hub-accounts: - # context: org-global - # requires: - # - build-local-onboard-hub-accounts - # filters: - # branches: - # ignore: - # - /feature*/ - # - /bugfix*/ - # - /hotfix*/ - # - image-scan-onboard-central-ledger: - # context: org-global - # requires: - # - build-local-onboard-central-ledger - # filters: - # branches: - # ignore: - # - /feature*/ - # - /bugfix*/ - # - /hotfix*/ - # - image-scan-onboard-msisdn-oracle: - # context: org-global - # requires: - # - build-local-onboard-msisdn-oracle - # filters: - # branches: - # ignore: - # - /feature*/ - # - /bugfix*/ - # - /hotfix*/ + - /.*/ + # New commits to master release automatically - release: context: org-global @@ -988,7 +539,6 @@ workflows: - test-coverage - vulnerability-check - audit-licenses - - test-integration - license-scan - image-scan filters: @@ -1013,7 +563,6 @@ workflows: - test-coverage - vulnerability-check - audit-licenses - - test-integration - license-scan - image-scan filters: From 1880d2cf93a8d804f041cbf15e47c41e240f6f1a Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 17:09:08 +0930 Subject: [PATCH 28/34] fix(ci): fix ci --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 61bb045d..16bd41c0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -80,6 +80,7 @@ jobs: - run: name: Install general dependencies command: *defaults_Dependencies + - checkout - run: name: Update NPM install (using `npm ci`) command: cd src && npm ci From 008055a4ee8850515497d9ec6d8e641406326c37 Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 17:16:11 +0930 Subject: [PATCH 29/34] fix(ci): fix ci --- src/package-lock.json | 1064 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1058 insertions(+), 6 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index 06ad00a0..ad98d5d0 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -402,6 +402,12 @@ "@hapi/hoek": "^9.0.0" } }, + "@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true + }, "@internal/log": { "version": "file:lib/log", "requires": { @@ -623,7 +629,8 @@ "lodash": "^4.17.12", "mute-stream": "0.0.7", "string-width": "^2.1.0", - "strip-ansi": "^5.1.0" + "strip-ansi": "^5.1.0", + "through": "^2.3.6" }, "dependencies": { "ansi-regex": { @@ -936,6 +943,12 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, "@types/node": { "version": "15.12.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.1.tgz", @@ -947,6 +960,16 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -978,6 +1001,12 @@ "integrity": "sha512-mjmzmv12YIG/G8JQdQuz2MUDShEJ6teYpT5bmWA4q7iwoGen8xtt3twF3OvzIUl+Q06aWIjvnwQUKvQ6TtMRjg==", "dev": true }, + "add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", + "dev": true + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -1159,6 +1188,12 @@ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, "array-includes": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", @@ -1641,6 +1676,25 @@ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, "caniuse-lite": { "version": "1.0.30001235", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001235.tgz", @@ -1884,6 +1938,16 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1966,6 +2030,401 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "conventional-changelog": { + "version": "3.1.24", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.24.tgz", + "integrity": "sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + } + }, + "conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-config-spec": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", + "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", + "dev": true + }, + "conventional-changelog-conventionalcommits": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.5.0.tgz", + "integrity": "sha512-buge9xDvjjOxJlyxUnar/+6i/aVEVGA7EEh4OafBCXPlLUQPGbRUBhBUveWRxzvR8TEjhKEP4BdepnpG2FSZXw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + } + }, + "conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "dev": true, + "requires": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "is-core-module": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", + "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, + "conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true + }, + "conventional-changelog-writer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz", + "integrity": "sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g==", + "dev": true, + "requires": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.2.tgz", + "integrity": "sha512-Jr9KAKgqAkwXMRHjxDwO/zOCDKod1XdAESHAGuJX38iZ7ZzVti/tvVoysO0suMsdAObp9NQ2rHSsSbnAqZ5f5g==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, + "conventional-recommended-bump": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", + "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "dev": true, + "requires": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.0", + "git-raw-commits": "^2.0.8", + "git-semver-tags": "^4.1.1", + "meow": "^8.0.0", + "q": "^1.5.1" + }, + "dependencies": { + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -2021,6 +2480,12 @@ "array-find-index": "^1.0.1" } }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2038,6 +2503,12 @@ "time-zone": "^1.0.0" } }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -2059,6 +2530,24 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", @@ -2167,11 +2656,23 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true + }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2213,6 +2714,52 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" }, + "dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, "duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -2998,6 +3545,15 @@ "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, "fs-minipass": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", @@ -3127,6 +3683,29 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "requires": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "get-stdin": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", @@ -3142,12 +3721,92 @@ "pump": "^3.0.0" } }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-raw-commits": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", + "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "requires": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "requires": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, "requires": { - "assert-plus": "^1.0.0" + "ini": "^1.3.2" } }, "glob": { @@ -3244,6 +3903,19 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -3271,6 +3943,12 @@ } } }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3770,6 +4448,15 @@ "has-symbols": "^1.0.2" } }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -4084,6 +4771,12 @@ "json-buffer": "3.0.0" } }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -4280,6 +4973,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, "lodash.isobjectlike": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/lodash.isobjectlike/-/lodash.isobjectlike-4.0.0.tgz", @@ -4397,6 +5096,12 @@ "p-defer": "^1.0.0" } }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, "matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -4452,6 +5157,91 @@ "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", "dev": true }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "is-core-module": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", + "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + } + } + }, "merge-options": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz", @@ -4502,6 +5292,12 @@ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -4515,6 +5311,25 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } + } + }, "minipass": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", @@ -4710,6 +5525,12 @@ "minimist": "^1.2.5" } }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4756,6 +5577,12 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -5460,6 +6287,12 @@ "set-blocking": "~2.0.0" } }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -6239,6 +7072,12 @@ "escape-goat": "^2.0.0" } }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, "qs": { "version": "6.10.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", @@ -6253,6 +7092,12 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, "raw-body": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", @@ -6512,6 +7357,16 @@ "picomatch": "^2.2.1" } }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", @@ -6927,6 +7782,37 @@ "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "dev": true }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "requires": { + "readable-stream": "^3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -7052,6 +7938,127 @@ } } }, + "standard-version": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.3.1.tgz", + "integrity": "sha512-5qMxXw/FxLouC5nANyx/5RY1kiorJx9BppUso8gN07MG64q2uLRmrPb4KfXp3Ql4s/gxjZwZ89e0FwxeLubGww==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "conventional-changelog": "3.1.24", + "conventional-changelog-config-spec": "2.1.0", + "conventional-changelog-conventionalcommits": "4.5.0", + "conventional-recommended-bump": "6.1.0", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "dotgitignore": "^2.1.0", + "figures": "^3.1.0", + "find-up": "^5.0.0", + "fs-access": "^1.0.1", + "git-semver-tags": "^4.0.0", + "semver": "^7.1.1", + "stringify-package": "^1.0.1", + "yargs": "^16.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -7107,6 +8114,12 @@ "safe-buffer": "~5.1.0" } }, + "stringify-package": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", + "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", + "dev": true + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -7122,6 +8135,15 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -7240,11 +8262,22 @@ "minimatch": "^3.0.4" } }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -7296,6 +8329,12 @@ "punycode": "^2.1.1" } }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, "trim-off-newlines": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", @@ -7371,6 +8410,13 @@ "is-typedarray": "^1.0.0" } }, + "uglify-js": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", + "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", + "dev": true, + "optional": true + }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -7611,6 +8657,12 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", From 1c7fb8d4ff813d88bf347e32f4838cea4ad0f996 Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Tue, 5 Oct 2021 17:21:03 +0930 Subject: [PATCH 30/34] chore: fix linting --- src/index.js | 2 -- src/lib/objectStore/inMemoryImpl.js | 1 - src/models/constants.js | 1 - src/simulator/handlers.js | 2 +- src/test-api/client.js | 1 - src/test/constants.js | 2 -- src/test/simulator.js | 21 ++++++++++----------- 7 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/index.js b/src/index.js index 9ab9d5e1..70a3ccc1 100644 --- a/src/index.js +++ b/src/index.js @@ -66,7 +66,6 @@ const testApi = new Koa(); with interoperability headers and doesn't parse properly the request body */ - // map where keys are the content-type values to be rewritten, extend it if needed const rewriteContentTypes = { 'application/vnd.interoperability.authorizations+json;version=1.0': 'application/json', @@ -83,7 +82,6 @@ async function rewriteContentTypeHeader(ctx, next) { await next(); } - (async function start() { // Set up the config from the environment await setConfig(process.env); diff --git a/src/lib/objectStore/inMemoryImpl.js b/src/lib/objectStore/inMemoryImpl.js index e64e3b7c..3f74ac99 100644 --- a/src/lib/objectStore/inMemoryImpl.js +++ b/src/lib/objectStore/inMemoryImpl.js @@ -1,4 +1,3 @@ - /***** License -------------- diff --git a/src/models/constants.js b/src/models/constants.js index 605b6b99..657786b9 100644 --- a/src/models/constants.js +++ b/src/models/constants.js @@ -149,5 +149,4 @@ module.exports = { createPartyExtensionTableUniqueIndex, partyAccountsTable, createAccountTable, - createTransferTable, }; diff --git a/src/simulator/handlers.js b/src/simulator/handlers.js index b683db24..ef98ba73 100644 --- a/src/simulator/handlers.js +++ b/src/simulator/handlers.js @@ -29,7 +29,7 @@ const util = require('util'); const crypto = require('crypto'); require('dotenv').config(); const { getStackOrInspect } = require('@internal/log'); -const { ApiErrorCodes } = require('../models/errors.js'); +const { ApiErrorCodes } = require('../models/errors'); const objectStore = require('../lib/objectStore/objectStoreInterface'); const getParticipantsByTypeAndId = async (ctx) => { diff --git a/src/test-api/client.js b/src/test-api/client.js index d41f8bae..a4c6425f 100644 --- a/src/test-api/client.js +++ b/src/test-api/client.js @@ -91,7 +91,6 @@ const postBulkQuotes = async (body) => { return res.json(); }; - module.exports = { postTransfers, putTransfers, diff --git a/src/test/constants.js b/src/test/constants.js index a5166078..8fa97a4b 100644 --- a/src/test/constants.js +++ b/src/test/constants.js @@ -95,7 +95,6 @@ const partyCreate = { ], }; - const partyCreateWithSubIdValue = { displayName: randName, firstName: randName.split(' ')[0] || '', @@ -458,7 +457,6 @@ module.exports = { quote, newQuote, quoteWithExtensionList, - newQuote, newQuoteWithExtensionList, bulkQuote, newBulkQuote, diff --git a/src/test/simulator.js b/src/test/simulator.js index 2d16370a..6db934e3 100644 --- a/src/test/simulator.js +++ b/src/test/simulator.js @@ -30,17 +30,17 @@ const { cloneDeep } = require('./unit/TestUtils'); const Model = require('../models/model'); const { map } = require('../simulator/handlers'); const { - transfer, - transferWithoutQuote, - quote, - transactionrequest, - party, - idType, + transfer, + transferWithoutQuote, + quote, + transactionrequest, + party, + idType, idValue, - transactionRequestId, - bulkQuote, - bulkTransfer, - bulkTransferId, + transactionRequestId, + bulkQuote, + bulkTransfer, + bulkTransferId, authorizationRequest, } = require('./constants'); const { ApiErrorCodes } = require('../models/errors'); @@ -139,7 +139,6 @@ test('post validate authToken valid', async (t) => { t.is(t.context.response.status, 200); }); - test('post validate authToken invalid', async (t) => { // eslint-disable-next-line no-param-reassign t.context.request = { From 11e744791e2992cf07fb92facdb312919f1d2a48 Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Wed, 6 Oct 2021 10:11:25 +0930 Subject: [PATCH 31/34] fix: ci --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 16bd41c0..8bceff84 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -505,11 +505,11 @@ workflows: - vulnerability-check - audit-licenses filters: + tags: + only: /v[0-9]+(\.[0-9]+)*(\-snapshot)?(\-hotfix(\.[0-9]+))?/ branches: ignore: - - /feature*/ - - /bugfix*/ - - /hotfix*/ + - /.*/ - license-scan: context: org-global requires: From a49d58735425e7cef199caf6ce8dfa1d5f59c226 Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Wed, 6 Oct 2021 10:16:29 +0930 Subject: [PATCH 32/34] fix: ci --- .circleci/config.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8bceff84..3dd4bde0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,11 +1,6 @@ # CircleCI v2.1 Config version: 2.1 - -# TODO! this config file is a real mess. -# how can we improve it? Can we also add -# auto-releases at the same time? - ## # orbs # From 02eedd35c67d1d0152d5ac6bda6c65a8bf016d9b Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Wed, 6 Oct 2021 10:23:09 +0930 Subject: [PATCH 33/34] fix: ci --- .circleci/config.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3dd4bde0..551e9878 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -353,7 +353,7 @@ jobs: <<: *defaults_license_scanner - run: name: Run the license-scanner - command: cd /tmp/license-scanner && mode=docker dockerImages=mojaloop/$CIRCLE_PROJECT_REPONAME:local make run + command: cd /tmp/license-scanner && mode=docker dockerImages=mojaloop/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG make run - store_artifacts: path: /tmp/license-scanner/results prefix: licenses @@ -373,7 +373,7 @@ jobs: command: docker load -i /tmp/docker-image.tar - anchore/analyze_local_image: dockerfile_path: ./Dockerfile - image_name: mojaloop/${CIRCLE_PROJECT_REPONAME}:local + image_name: mojaloop/${CIRCLE_PROJECT_REPONAME}:$CIRCLE_TAG # Anchore bug: if policy_failure is `true`, reports don't get written - we manually check for failures below policy_failure: false timeout: '500' @@ -423,9 +423,9 @@ jobs: docker push $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG # publish init images - docker push $DOCKER_ORG/onboard-hub-accounts:$RELEASE_TAG - docker push $DOCKER_ORG/onboard-msisdn-oracle:$RELEASE_TAG - docker push $DOCKER_ORG/onboard-central-ledger:$RELEASE_TAG + docker push $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG + docker push $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG + docker push $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG - slack/status: webhook: "$SLACK_WEBHOOK_ANNOUNCEMENT" success_message: '*"${CIRCLE_PROJECT_REPONAME}"* - Release \`"${CIRCLE_TAG}"\` \nhttps://github.com/mojaloop/"${CIRCLE_PROJECT_REPONAME}"/releases/tag/"${CIRCLE_TAG}"' From 35d7a9518048401d2151aaef9c4d897ff3d94b3d Mon Sep 17 00:00:00 2001 From: Lewis Daly Date: Wed, 6 Oct 2021 10:31:47 +0930 Subject: [PATCH 34/34] fix: ci --- .circleci/config.yml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 551e9878..1581631d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,11 +42,6 @@ defaults_license_scanner: &defaults_license_scanner git clone https://github.com/mojaloop/license-scanner /tmp/license-scanner cd /tmp/license-scanner && make build default-files set-up -src_working_directory: &src_working_directory - # The working directory for this project (place where package.json is) is /src, - # as opposed to the project root - working_directory: ~/git/src - ## # Executors # @@ -251,7 +246,6 @@ jobs: git fetch origin git checkout origin/${CIRCLE_BRANCH} - run: - # Note: this is rather imperfect, but will do for now name: Format the changelog into the github release body and get release tag command: | git diff --no-indent-heuristic master~1 HEAD CHANGELOG.md | sed -n '/^+[^+]/ s/^+//p' > /tmp/changes @@ -402,7 +396,7 @@ jobs: at: /tmp - run: name: Load the pre-built docker images from workspace - command: > + command: | docker load -i /tmp/docker-image.tar docker load -i /tmp/docker-onboard-hub-accounts.tar docker load -i /tmp/docker-onboard-msisdn-oracle.tar @@ -411,7 +405,7 @@ jobs: name: Login to Docker Hub command: docker login -u $DOCKER_USER -p $DOCKER_PASS - run: - name: Re-tag pre built image + name: Re-tag pre built image with :latest tag command: | docker tag $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$CIRCLE_TAG $DOCKER_ORG/$CIRCLE_PROJECT_REPONAME:$RELEASE_TAG - run: @@ -426,10 +420,6 @@ jobs: docker push $DOCKER_ORG/onboard-hub-accounts:$CIRCLE_TAG docker push $DOCKER_ORG/onboard-msisdn-oracle:$CIRCLE_TAG docker push $DOCKER_ORG/onboard-central-ledger:$CIRCLE_TAG - - slack/status: - webhook: "$SLACK_WEBHOOK_ANNOUNCEMENT" - success_message: '*"${CIRCLE_PROJECT_REPONAME}"* - Release \`"${CIRCLE_TAG}"\` \nhttps://github.com/mojaloop/"${CIRCLE_PROJECT_REPONAME}"/releases/tag/"${CIRCLE_TAG}"' - ## # Workflows # @@ -456,6 +446,8 @@ workflows: requires: - setup filters: + tags: + only: /.*/ branches: ignore: - /feature*/ @@ -466,6 +458,8 @@ workflows: requires: - setup filters: + tags: + only: /.*/ branches: ignore: - /feature*/ @@ -476,6 +470,8 @@ workflows: requires: - setup filters: + tags: + only: /.*/ branches: ignore: - /feature*/ @@ -486,6 +482,8 @@ workflows: requires: - setup filters: + tags: + only: /.*/ branches: ignore: - /feature*/