JS Framework featuring advanced authorization
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
client Fix gitignore Jan 13, 2019
server Add server/core tests Jan 13, 2019
.gitignore Fix repo Oct 6, 2018
README.md Fix README Jan 11, 2019

README.md

Fullstack Javascript Framework

"By the power combined I am... FullstackJS" 💥 😎

WARNING: this is an ongoing work. Don't use in production yet!

Featuring

Modular architecture

Server Module: folder with module name containing

  1. gql folder with .gql files
  2. resolvers.js (Graphql resolvers)
  3. routes.js (Koa routes)

Client Module: folder with module name containing:

  1. Routes.js

Advanced Authorization

Role based + Policy based authorization using:

  1. User - The authenticated object
  2. Role - Group for permissions and policies
  3. Resource - Currently supports Graphql resolver and Koa Router's path
  4. Permission - Access (allow/deny) for Role/Resource
  5. Policy (or hook) - IN-code function, allows to use input args for fine-grained permissions
  6. Policy Bypass - Allows to bypass/enforce policies for given roles
  7. Cache for faster resolution

Server

  1. KnexJS - For database connections and migrations
  2. ObjectionJS - ORM
  3. Apollo Server - GraphQL server
  4. Koa - NodeJS web framework

Client

  1. ReactJS - React app created with CRA
  2. Semantic UI - CSS framework
  3. Batteries included: Backend starter with Authorization Management UI

Install Server

$ cd server
$ npm install
$ npm i knex -g
$ cp .env.example .env # Edit .env with your configuration
$ knex migrate:latest
$ mkdir cache
$ node updateCache.js
$ knex seed:run
$ node updateCache.js

Start Server

$ node app.js &

Open in browser http://localhost:4000/graphql
Enter query and run:

query getHello { getHello(name: "world") { name } }

Install Client

$ cd client
$ npm install
$ cp .env.example .env # Edit .env with your configuration

Test Client

$ npm run start

Build, Deploy Client on Server and Open Application

$ cd client
$ npm run build
$ npm run deploy

Open http://localhost:4000
Login with (look at the code)


Hello World Module Example

1. Server Module Structure

/root
../modules
../../enabled
../../../helloworld
../../../../gql
../../../../../queries.gql
../../../../../types.gql
../../../../HelloWorld.js
../../../../resolvers.js
../../../../routes.js

1.1. queries.gql

getHello(name: String!): Hello

1.2. types.gql

type Hello {
  name: String
}

At this point, the framework will generate the following schema.gql automatically:
/cache/schema.gql

Queries {
  getHello(name: String!): Hello
}
type Hello {
  name: String
}

1.3. HelloWorld.js

class HelloWorld {
  static async talkTo(name) {
    return new Promise(resolve => {
      resolve(`Hello ${name}!`);
    });
  }
}
module.exports = HelloWorld;

1.4. resolvers.js

const HelloWorld = require('./HelloWorld');

module.exports = {
  Query: {
    getHello: async (root, args, context) => {
      const name = await HelloWorld.talkTo(args.name);
      return { name };
    }
  }
}

1.5. routes.js

module.exports = (app, router) => {
  router.get('/hello/:name', async (ctx, next) => {
    ctx.body = 'Hello ' + ctx.params.name;
  });
}

2. Client Module Structure /src
../modules
../../welcome
../../../Routes.js

2.1 Routes.js

import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import Welcome from './Welcome';

class Routes extends Component {
  render() {
    return (
      <Route exact path="/" component={Welcome} />
    );
  }
}
export default Routes;

Module routes will be loaded using the Loadable lib