Skip to content

Commit

Permalink
Add more stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Araan Branco committed Mar 10, 2017
1 parent 6c63c60 commit 9e8c8b5
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 3 deletions.
20 changes: 20 additions & 0 deletions controllers/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

import Boom from 'boom';
import * as db from '../helpers/db';

export const login = async(request, reply) => {
const { User } = db.connect('sofanerd').connection.models;
let { username, password } = request.payload;
let user = await User.findOne({
username
});

if(!user || !await user.checkPassword(password)) {
return reply(Boom.unauthorized('Credentials invalid!'));
}

reply({
token: user.getToken(),
user
});
};
15 changes: 15 additions & 0 deletions controllers/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

import Boom from 'boom';
import * as db from '../helpers/db';

export const create = async(request, reply) => {
const { User } = db.connect('sofanerd').connection.models;

let user = new User(request.payload);
user = await user.save();

reply({
token: user.getToken(),
user
});
};
13 changes: 13 additions & 0 deletions helpers/bcrypt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

import bcrypt from 'bcrypt';
import Bluebird from 'bluebird';

// Generate Hash with Bcrypt
export const hash = (value) => bcrypt.hashSync(value, process.env.NODE_BCRYPT_SALT);

// Compare hashs passwords
export const compare = async (password, hash) => {
console.log(password, hash);
let compareAsync = Bluebird.promisify(bcrypt.compare);
return await compareAsync(password, hash);
};
14 changes: 14 additions & 0 deletions helpers/jwt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

import jwt from 'jsonwebtoken';

export const generate = (payload, audience) => {
let aud = audience ? audience : 'api';
return jwt.sign(payload, process.env.NODE_JWT_SALT, {
algorithm: 'HS256',
audience: aud
});
};

export const decode = (token) => jwt.decode(token, { complete: true });

export const verify = (token, options) => jwt.verify(token, process.env.NODE_JWT_SALT, options);
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import Hapi from 'hapi';
import dotenv from 'dotenv';
import Debug from 'debug';
import JWT from 'hapi-auth-jwt2';
import Models from './models';
import Auth from './plugins/auth';
import Routes from './plugins/routes';

dotenv.config();
Expand All @@ -19,6 +21,8 @@ server.connection({
});

let initializer = [
JWT,
Auth,
Models,
Routes
];
Expand Down
2 changes: 1 addition & 1 deletion models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const debug = Debug('sofanerd.models');
const register = (server, options, next) => {
const dbConenction = db.connect('sofanerd').connection;

debug('Models initialize');
debug('Inicialize Models');
require('./movie').model(dbConenction);
require('./serie').model(dbConenction);
require('./user').model(dbConenction);
Expand Down
5 changes: 3 additions & 2 deletions models/schemas/user.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@

import mongoose from 'mongoose';
import { hash } from '../../helpers/bcrypt';

const Schema = mongoose.Schema;

const schema = new Schema({
username: { type: String },
name: { type: String },
email: { type: String },
password: { type: String },
roles: { type: Array, default: ['user', 'authenticated'] },
password: { type: String, set: hash },
roles: { type: Array, default: ['user'] },
favorites: [],
collections: [],
reactions: [{
Expand Down
25 changes: 25 additions & 0 deletions models/user.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@

import Debug from 'debug';
import Boom from 'boom';
import _ from 'lodash';
import schema from './schemas/user';
import * as jwt from '../helpers/jwt';
import { compare } from '../helpers/bcrypt';

const debug = Debug('sofanerd.models.user');

export const model = (connection) => {

// Generate Token JWT for the user
schema.methods.getToken = function({ aud = 'api' } = {}) {
let data = _.pick(this.toObject(), '_id');
return jwt.generate(data, aud);
};

// Check Password
schema.methods.checkPassword = async function(password) {
if(!this.password) {
throw Boom.badRequest('User not have password');
}

const comparePassword = await compare(password, this.password);
if(!comparePassword) {
throw Boom.badRequest('Password not match');
}

return true;
};

return connection.model('User', schema);
};
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@
"dependencies": {
"babel-cli": "^6.23.0",
"babel-preset-latest": "^6.22.0",
"bcrypt": "^1.0.2",
"bluebird": "^3.5.0",
"boom": "^4.2.0",
"debug": "^2.6.1",
"dotenv": "^4.0.0",
"glob": "^7.1.1",
"hapi": "^16.1.0",
"hapi-auth-jwt2": "^7.2.4",
"joi": "^10.2.2",
"jsonwebtoken": "^7.3.0",
"lodash": "^4.17.4",
"mongoose": "^4.8.6"
}
}
47 changes: 47 additions & 0 deletions plugins/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

import Debug from 'debug';
import Boom from 'boom';
import * as db from '../helpers/db';

const debug = Debug('sofanerd.authStrategy');

const register = (server, options, next) => {
try {
debug('Inicialize plugins');

server.auth.strategy('token-api', 'jwt', {
key: process.env.NODE_JWT_SALT,
async validateFunc(decoded, request, reply) {
const { User } = db.connect('sofanerd').connection.models;

let user = await User.findOne({
_id: decoded._id
});

if(!user) {
return reply(Boom.notFound('User not found'), false);
} else {
return reply(null, true, user);
}
},
verifyOptions: {
algorithms: ['HS256'],
audience: 'api'
}
});

debug('Plugins registered');
next();
} catch (err) {
debug(err);
throw err;
}
};

register.attributes = {
name: 'auth'
};

export default {
register
};
22 changes: 22 additions & 0 deletions routes/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

import Debug from 'debug';
import Joi from 'joi';
import * as Controller from '../controllers/auth';

const debug = Debug('sofanerd.routes.auth');

export default [
{
method: 'POST',
path: '/api/auth',
config: {
validate: {
payload: {
username: Joi.string().trim().lowercase().required(),
password: Joi.string().trim().token().min(5).max(40).required()
}
}
},
handler: Controller.login
}
];
26 changes: 26 additions & 0 deletions routes/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

import Debug from 'debug';
import Joi from 'joi';
import * as Controller from '../controllers/user';

const debug = Debug('sofanerd.routes.auth');

const userCreatePayloadValidation = Joi.object({
username: Joi.string().trim().lowercase().min(3).max(20).required(),
name: Joi.string().min(1).max(50).required(),
email: Joi.string().email().min(1).max(40).required(),
password: Joi.string().token().min(6).max(40).required()
});

export default [
{
method: 'POST',
path: '/api/user',
config: {
validate: {
payload: userCreatePayloadValidation
}
},
handler: Controller.create
}
];

0 comments on commit 9e8c8b5

Please sign in to comment.