Public Repository

Last pushed: a month ago
Short Description
Short description is empty for this repo.
Full Description

How to run (Windows)

DB

  • Download MySQL

    MySQL installer

  • Manually create the DBs.

    • dev database (With the same name as in config/variables)
    • test database (With the same name as in config/variables)

Config DB

  • Set character_set to utf8mb4

      SET character_set_client = 'utf8mb4';
      SET character_set_results = 'utf8mb4';
      SET character_set_connection = 'utf8mb4';
    
  • Check the changes

    SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%'

Config file

  • Copy and paste config/config-variables-demo.js to config/config-variables

  • Filling each of fields

Environment setup

You will need...

  • Install node with npm

    Node download

  • Install node globals that you'll need

    npm install -g grunt-cli lab knex

  • Install npm packages

    npm install

  • Update the database schema to the latest version

    grunt migrate

  • Seed the database with some sample data

    grunt seed

Running the server locally

Setting up a server

grunt serve
That's it

Testing

Use HapiJS lab tool
lab -v

For a smart triggering of test files use
grunt test
then save the test file you want to run. It'll run every time you save it. If you save a non test file, it'll run all tests.

Migrations

"grunt migrate" command

To perform database reset you should run:
grunt migrate

To perform database upgrade to the latest version you should run:
grunt migrate:latest

To perform database downgrade:
grunt migrate:rollback

To truncate all tables in a database (except migrations table):
grunt migrate:truncate

To drop all tables in a database (including migrations table):
grunt migrate:reset

If you want to create a new upgrade database file you should run:
grunt migrate:make:[migration_name]

If you want to execute the changes for the test environment

// Test Db reset to the latest version
grunt migrate:test
// Others, self explanatory
grunt migrate:test:rollback
grunt migrate:test:latest
grunt migrate:test:truncate
grunt migrate:test:reset
grunt migrate:test:make:[migration_name] // Rarely used

If you want to define any other environment
grunt migrate:[command] --env [env_name]

More info: https://github.com/p-baleine/grunt-knex-migrate

BaseController API

BaseController helps us create Hapi controllers.

Constructor function
Create controller with CRUD actions, named list, show, create, update, destroy

var Model = require('../models/Model');
var myCtrl = new BaseCtrl( Model );

Add or override action
myCtrl.addAction(actionName, handler, [needsParamId], [needsPagination]);
For example:

// Add a new action
myCtrl.addAction('validate', function(request, reply){ //handle here });

// Override an action, by using the existing name
myCtrl.addAction('update', function(request, reply){ //handle here }, true, false);

needsParamId: It is important to add a validation rule expecting 'id' in the uri. Furthermore, and even more important, it enforces later on the need to add a matching function that defines how to handle that id with regards to access permissions. For example, a normal user with id 100, can only have access to /users/100, but not to /users/101

Add validation rules
At this point no validations are enforced except for the ones generated by default when using the parameters needsParamId and needsPagination in the constructor function.

Currently, validation rules need to be added by action name.

myCtrl[ actionName ].addValidationRules( [targetValidator], validationObj);

targetValidator: If used, it has to be query, params or payload

validationObj: It is an object with Joi validations

Examples

usersCtrl['login'].addValidationRules('payload', {
  username: Joi.string(),
  ...
  }
);
// equivalent to...
usersCtrl['login'].addValidationRules(
  {
    payload: {
      username: Joi.string(),
      ...
    }
  }
);

Enable routes access - public access
All routes are still blacklisted by default and we need to explicitly open them.

myCtrl.makePublic(actions); // Actions can be a string or an array

Enable protected routes
Roles need to be added to routes to become accessible by that role
myCtrl.addRoles(actions, roles, matchingFunction) // Actions and roles can be strings or arrays

matchingFunction: A function only used when one or more of the roles contains a parameter id on the url, which has to evaluate whether to allow access or not to a specific request, usually based on comparing the url {id} against something else. The function has a signature like function(request){}, and has to return a boolean or a promise that resolves to a boolean.

Examples:

// (Synchronous example) Allow a user to modify only his own user information, but an admin to modify any.
usersCtrl.addRoles(['update'], "Client", function(request){

  // The id in the URI matches the logged in user.
  return request.params.id === request.auth.credentials.user.id;
});

usersCtrl.addRoles(['update'], "Administrator", function(request){
  return true;
});

// (Async example) Allow a Professional to access only his own orders
ordersCtrl.addRoles(['show'], "Professional", function(request){
  Orders.forge({id: request.params.id}).fetch().then(function(orders){
    return orders.professional_id === request.auth.credentials.user.id;
  });
});

ACL testing API

To ensure that endpoints are properly blocked without too verbosy testing, a helper module has been created. To use it we pass the base endpoint and lab object:

var AclTestHelper = require('../../app/helpers/utilities/aclTestHelper.js');
aclTestHelper = new AclTestHelper("/users", lab);

Adding testing targets by ENDPOINT
aclTestHelper.addTarget(endpoint, method, access)
endpoint: The route to the endpoint. If it contains ids, set it to a random number, as it doesnt matter for the purposes of the testing.
method: The method to be used (ie: GET, POST, etc)
access: String 'public' if public; or a string or array of possible roles.

Example:

aclTestHelper.addTarget(['/activate/1/1'], 'GET', 'public');

Adding testing targets by ACTION
aclTestHelper.addTarget(action, access)
action: The action name, prefixed by a hashbang (#);
access: String 'public' if public; or a string or array of possible roles.

Example:

aclTestHelper.addTarget(['#show', '#update'], ["Administrator", "Client"]);

Run the tests
After all targets are added, test must be manually triggered:

aclTestHelper.runTests();

API Documentation

The API documentation is ready to use (thanks to swagger) at http://localhost:3001/documentation

Docker Pull Command
Owner
ouendinga