Skip to content

Nodstarter is a starter application for Node.js, simple, preconfigured, secure, and lightweight.

License

Notifications You must be signed in to change notification settings

0xh3xa/nodstarter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nodstarter

nodstarter


Build Status Dependency Status Linux Mac Known Vulnerabilities License

starter application for Node.js to provide rapid Restful APIs development, pre-configured, secured routers, services, and models.

Table of contents

General info

Nodstarter is a starter application for Node.js to provide rapid Restful APIs development, pre-configured, secured routers, services, and models using different libraries.

This project aims to help writing the secure rest APIs quickly and provide a skeleton to the node.js project to minimize the configuration and avoid starting from scratch.

Technologies

  1. Node.js
  2. Express framework
  3. MongoDB
  4. Mongoose ORM
  5. Lodash
  6. Morgan middleware
  7. Body-parser middleware
  8. Method-override
  9. Bcrypt
  10. Express-jwt
  11. Jsonwebtoken
  12. Cors middleware
  13. Nodemon
  14. Testing libraries: Supertest, Chai and Mocha

Initial code

Nodstarter contains 3 models with the relationship to users, posts and categories, each of them contains router, controller, and model

  • Router: Already defined routers you can change to what you want

  • Controller: CRUD operation for the models

  • Model: Mongo representation for three models with the relationship:

    • User to Posts one-to-many
    • Posts to Categories many-to-many

So this is the basis for a node.js project you can start with any of them and change the router to your routes, and use the controller.

For the model also you can update them and the relationship is already this you can copy-and-paste.

In future plans ability to use a command line to create a router, controller, model like Ruby-on-Rails.

Project structure

├── index.js
├── package.json
├── scripts
│   └── post_install.js
└── server
    ├── api
    │   ├── categories
    │   │   ├── controller.js
    │   │   ├── model.js
    │   │   └── router.js
    │   ├── index.js
    │   ├── posts
    │   │   ├── controller.js
    │   │   ├── model.js
    │   │   └── router.js
    │   └── users
    │       ├── controller.js
    │       ├── model.js
    │       └── router.js
    ├── auth
    │   ├── controller.js
    │   ├── index.js
    │   └── routers.js
    ├── config
    │   ├── development.js
    │   ├── index.js
    │   ├── production.js
    │   └── testing.js
    ├── index.js
    ├── middleware
    │   ├── err.js
    │   └── index.js
    └── util
        ├── createRouter.js
        └── logger.js

AUTH Code snippet

This is the configuration to the JWT token to the user

JWT configuration

const expressJwt = require('express-jwt');
const config = require('../config');
const logger = require('../util/logger');
const jwt = require('jsonwebtoken');
const checkToken = expressJwt({
    secret: config.secrets.jwt
});
const User = require('../api/users/model');
exports.decodeToken = () => {
    return (req, res, next) => {
        if (req.query && req.query.hasOwnProperty('access_token')) {
            req.headers.authorization = 'Bearer ' + req.query.access_token;
        }
        checkToken(req, res, next);
    };
};

exports.getFreshUser = () => {
    return (req, res, next) => {
        User.findById(req.user._id)
            .then((user) => {
                if (!user) {
                    res.status(400).send('Unanuthorized');
                } else {
                    req.user = user;
                    next();
                }
            }, (err) => {
                next(err);
            });
    };
};

exports.verifyUser = () => {
    return (req, res, next) => {
        var username = req.body.username;
        var password = req.body.password;

        if (!username || !password) {
            res.status(400).send('You need a username and password');
            return;
        }

        User.findOne({
                username: username
            })
            .then((user) => {
                logger.log('the selected user from DB: ' + user);
                if (!user) {
                    logger.log('No user with the given username');
                    res.status(401).send('Invalid username or password');
                } else if (!user.authenticate(password)) {
                    logger.log('Invalid password');
                    res.status(401).send('Invalid username or password');
                } else {
                    req.user = user;
                    next();
                }
            }, (err) => {
                next(err);
            });
    };
};

exports.signToken = (id) => {
    logger.log("id is: " + id);
    return jwt.sign({
        _id: id
    }, config.secrets.jwt, {
        expiresIn: config.expireTime
    });
};

Sign in API call example

curl --header "Content-Type: application/json" --request POST --data '{"username":"test_user_4","password":"12345"}' http://localhost:3000/auth/signin

, Output

{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZTY2NjQwODYzMGE0NDE3MThiMjNhMzgiLCJpYXQiOjE1ODQ2Mzc4NDIsImV4cCI6MTU4NDY1MjI0Mn0.MODWP86ebc8XOMjDGyuvNCWWoKnQhpZpl81ynFGExG8"}

Environment variables

Nodstarter starts searching first for the following environment variables if found them will use them if not will use the default. The default values for NODE_ENV is development, NODE_PORT is 3000 and JWT is Gambell You can choose the environment for the NODE_ENV variable from one of the following profiles (development, production, testing)

  1. NODE_ENV
  2. NODE_PORT
  3. JWT

Setup

  1. Init with npm:
$ npm init
  1. Install:
$ npm install nodstarter
  1. Start:
$ npm start

, or use in one-line command:

$ npm init; npm install nodstarter; npm start

Before running

Please make sure that the MongoDB daemon is up and running

  • Ubuntu
systemctl start mongodb
  • Macos
brew services run mongodb-community

Demo

Demo

Running Tests (future plan)

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

$ npm install && npm test

Future plans

  1. Swagger file for the existing APIs
  2. Add tests for the existing APIs
  3. Ability to make nodstarter a command line to install models, controllers and routers, etc.

New Ideas

If you have new ideas about the project please describe what you want to do and changes using an issue.

Contributing

See CONTRIBUTING.md

License summary

See License

NPM statistics

NPM

Project based

nodejs    nodejs    nodejs