Skip to content

Latest commit

 

History

History
178 lines (136 loc) · 10.1 KB

README.md

File metadata and controls

178 lines (136 loc) · 10.1 KB

My Banking App

Build Status Maintenance License: MIT

This app is a backend that manages your user's financial data using Truelayer's secure banking API's over HTTP.

Pre-requisities:

Some key things to set up / understand to use this app:

Downloading

$ git clone https://github.com/mayankamencherla/truelayer-interview-app.git

Setup Locally

To get the app working locally, or to run test cases, follow the instructions below. After setting up the app, details on each API and how to use it can be found below in the API's available on this app section. If any of the commands below are denied due to a permission error, please prepend a sudo to the command.

  1. Navigate to the app's root directory

  2. Run the following command to install all the dependencies:

$ npm install
  1. Copy over .env.sample to .env in the root of the project
$ cp .env.sample .env
  1. Change the values of the environment variables in .env file based on requirement. Please sign-up for Truelayer and input your clientId and secret in this file. These variables are required for the app to run. More details here.

  2. Set up redis on your machine from here. Redis needs to be started using redis-server for the app to work fully.

  3. Set up mysql on your machine from here

  4. Log in to your mysql instance locally, and run the following commands:

mysql> DROP DATABASE IF EXISTS banking_app;
mysql> CREATE DATABASE banking_app;
  1. To get your local mysql to bind to the app, you must first copy over the sample knexfile. The app has root@password as the default configuration, which must be changed in development to suit the credentials on your local MySQL instance. You can change this in the knexfile-sample.js file before executing the command below:
$ cd server && cp knexfile-sample.js knexfile.js && cd ..
  1. The final step in setting up the DB is to run migrations. Please use the following commands from the app's root directory:
$ npm i knex -g
$ cd server && knex migrate:latest && cd ..
  • If the command above doesn't work, please try running the command below:
$ npm run migrate
  1. Run the app on localhost by typing the following command:
$ npm start
  1. Head over to localhost:3000 on your browser to use the app

  2. To test out the /user/transactions and /user/transactions/stats routes, the recommended tool would be Postman

  3. After setting up the app locally, you could alternatively run the app via Docker. Please use the commands below to do that:

$ sudo docker-compose build
$ sudo docker-compose up

Note: The sudo docker-compose up command would likely fail to set up MySQL the first time after running the build command. Please exit, and run the command again when this happens.

Run tests

  1. To run tests the following command would work:
$ npm test
  1. But many tests require a valid Truelayer access token. These tests can run by following the steps outlined below:
    a. Head over to the AuthenticationController.js file
    b. console.log(tokens) right below line 26
    c. Open localhost:3000 after setting up the app using the instructions above
    d. Complete the authentication / authorization flow
    e. The terminal's logs will contain the access_token and renewal_token
    f. Copy them over to the .env file and paste them in their respect places
    g. Run npm test to see all the tests executing

Run using Docker

The docker image for this app is available for download from our docker hub. You must have Docker installed in your system. Docker has extensive installation guideline for popular operating systems. Choose your operating system and follow the instructions.

Ensure you that you have docker installed and running in your system before proceeding with next steps. A quick test to see if docker is installed correctly is to execute the command docker run hello-world and it should run without errors.

  1. Set up the MySQL container
$ sudo docker run -e MYSQL_DATABASE='banking_app' -e MYSQL_ROOT_PASSWORD='password' -d --name mysql mayankamencherla/bankingapp_mysql:latest
  1. Set up the Redis container
$ sudo docker run -d --name redis redis
  1. Set up the app container and link it to the MySQL and Redis containers
$ sudo docker run -e NODE_ENV=production --link mysql:mysql --link redis:redis --rm -p 3000:3000 mayankamencherla/banking_app:latest

Logging

Logging is set up already in the app using winston The application's logger will log to storage/logs/debug.log as a json

Environment variables

Environment variables are picked up from the .env file, which must be created in the app's root directory. The root directory has a sample file called .env.sample that contains all the necessary config variables, but they must be changed in the .env file correctly for the application to work

Some key environment variables are listed and explained below:

  1. CLIENT_ID is the Truelayer API client ID which must be generated after signing here

  2. CLIENT_SECRET is the Truelayer API client secret, which can be retreived from the account after signing up using the link above

  3. REDIRECT_URI is the url that must be sent to Truelayer which is will get the callback response after user access / rejects app authorization

  4. JWT_SECRET is the secret used to generate the app's json web token

  5. AES_KEY is the key used to encrypt and decrypt Truelayer's access and refresh token before storing in the DB / after retreiving from the DB, and the string needs to be of length 32 (256 bits) as we are using AES-256-CTR mode

  6. AES_IV is the initialization vector used for AES, and needs to be of length 16 (128 bits)

Securely storing Truelayer tokens

Truelayer's access and refresh tokens are stored in the DB, which means they can be compromised if not stored securely. The points below outline the steps taken by the application to store the OAuth2.0 tokens securely in the DB.

  1. Truelayer's access / refresh tokens are encrypted using the AES-256-CTR algorithm before storing in the DB. This step requires that the unique key must be updated in the AES_KEY environment variable in the .env file. A random IV must also be updated in the AES_IV environment variable.

  2. When the app token is sent across to the API's, during the authentication step, we decrypt the encrypted Truelayer tokens using the AES-256-CTR algorithm again before sending it to Truelayer for further processing

  3. There is currently a security breach in the methodology used above. This is outlined below:

Note: CTR mode requires that every encryption / decryption must happen with a unique secure IV. An IV used once to encrypt an access_token, can only be used once to decrypt it for usage, and then should be discarded. A new IV must be generated each time after the old one is used, and must be used to re-encrypt the access_token, and so on. Currently, this is not the case, as the same IV is used over and over again. Another industry standard encryption scheme for this use case is the AES-GCM algorithm, which is an envelope encryption algorithm for authenticated encryption.

API's available on this app

This app supports 3 API's currently

  1. GET /

    • allows you to sign up on the app using Truelayer's oAuth2.0 authentication / authorization flow.
    • Returns an app auth token as a header (x-auth)
    • The returned header must be stored to make subsequent requests on behalf of the registered user.
  2. GET /user/transactions

    • allows you to fetch signed up user's transactions using app token generated in the step above.
    • Valid app token must be sent as x-auth header and is used to authenticate the user.
    • Programmatically check the x-auth header in the response to ensure new token is saved when generated. New token token generation happens when Truelayer access token is expired.
    • The API returns all of the user's transactions across accounts
  3. GET /user/transactions/stats

    • allows you to generate statistics based on the transactions saved in the API above.
    • Valid app token must be sent as x-auth header and is used to authenticate the user.
    • API must be called after user/transactions API has been called at least once, as this API simply pulls the information out from the DB / Redis
    • The API returns the user's transaction stats grouped by transaction category, across accounts