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