@@ -1,7 +1,9 @@
import Base from './components/Base.jsx';
import HomePage from './components/HomePage.jsx';
import DashboardPage from './containers/DashboardPage.jsx';
import LoginPage from './containers/LoginPage.jsx';
import SignUpPage from './containers/SignUpPage.jsx';
import Auth from './modules/Auth';


const routes = {
@@ -11,7 +13,13 @@ const routes = {

{
path: '/',
component: HomePage
getComponent: (location, callback) => {
if (Auth.isUserAuthenticated()) {
callback(null, DashboardPage);
} else {
callback(null, HomePage);
}
}
},

{
@@ -22,6 +30,16 @@ const routes = {
{
path: '/signup',
component: SignUpPage
},

{
path: '/logout',
onEnter: (nextState, replace) => {
Auth.deauthenticateUser();

// change the current URL to /
replace('/');
}
}

]
@@ -1,4 +1,4 @@
{
"dbUri": "mongodb://ubcfarm:tomatoes@ds141960.mlab.com:41960/ubc-farm-test",
"dbUri": "mongodb://localhost/data",
"jwtSecret": "a secret phrase!!"
}
@@ -19,9 +19,11 @@
"express": "^4.14.0",
"jsonwebtoken": "^7.4.0",
"material-ui": "^0.16.4",
"mongodb": "^2.2.26",
"mongoose": "^4.9.9",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"prop-types": "^15.5.10",
"react": "^15.4.1",
"react-dom": "^15.4.1",
"react-router": "^3.0.0",
@@ -0,0 +1,40 @@
/*
**Author: Xingyu Tao
**Last Updated: 5-15-2017
**Comments:
** checks if authroization header exists in http request, decode token
*/

const jwt = require('jsonwebtoken');
const User = require('mongoose').model('User');
const config = require('../../config');


/**
* The Auth Checker middleware function.
*/
module.exports = (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).end();
}

// get the last part from a authorization header string like "bearer token-value"
const token = req.headers.authorization.split(' ')[1];

// decode the token using a secret key-phrase
return jwt.verify(token, config.jwtSecret, (err, decoded) => {
// the 401 code is for unauthorized status
if (err) { return res.status(401).end(); }

const userId = decoded.sub;

// check if a user exists
return User.findById(userId, (userErr, user) => {
if (userErr || !user) {
return res.status(401).end();
}

return next();
});
});
};
@@ -0,0 +1,63 @@
/*
**Author: Xingyu Tao
**Last Updated: 5-15-2017
**Comments:
** local login strategy for passport
*/

const jwt = require('jsonwebtoken');
const User = require('mongoose').model('User');
const PassportLocalStrategy = require('passport-local').Strategy;
const config = require('../../config');


/**
* Return the Passport Local Strategy object.
*/
module.exports = new PassportLocalStrategy({
usernameField: 'email',
passwordField: 'password',
session: false,
passReqToCallback: true
}, (req, email, password, done) => {
const userData = {
email: email.trim(),
password: password.trim()
};

// find a user by email address
return User.findOne({ email: userData.email }, (err, user) => {
if (err) { return done(err); }

if (!user) {
const error = new Error('Incorrect email or password');
error.name = 'IncorrectCredentialsError';

return done(error);
}

// check if a hashed user's password is equal to a value saved in the database
return user.comparePassword(userData.password, (passwordErr, isMatch) => {
if (err) { return done(err); }

if (!isMatch) {
const error = new Error('Incorrect email or password');
error.name = 'IncorrectCredentialsError';

return done(error);
}

const payload = {
sub: user._id
};

// create a token string
const token = jwt.sign(payload, config.jwtSecret);
const data = {
name: user.name
};

return done(null, token, data);
});
});
});
@@ -6,6 +6,7 @@
*/
const express = require('express');
const validator = require('validator');
const passport = require('passport');

const router = new express.Router();

@@ -80,7 +81,7 @@ function validateLoginForm(payload) {
};
}

router.post('/signup', (req, res) => {
router.post('/signup', (req, res, next) => {
const validationResult = validateSignupForm(req.body);
if (!validationResult.success) {
return res.status(400).json({
@@ -90,10 +91,35 @@ router.post('/signup', (req, res) => {
});
}

return res.status(200).end();

return passport.authenticate('local-signup', (err) => {
if (err) {
if (err.name === 'MongoError' && err.code === 11000) {
// the 11000 Mongo code is for a duplication email error
// the 409 HTTP status code is for conflict error
return res.status(409).json({
success: false,
message: 'Check the form for errors.',
errors: {
email: 'This email is already taken.'
}
});
}

return res.status(400).json({
success: false,
message: 'Could not process the form.'
});
}

return res.status(200).json({
success: true,
message: 'You have successfully signed up! Now you should be able to log in.'
});
})(req, res, next);
});

router.post('/login', (req, res) => {
router.post('/login', (req, res, next) => {
const validationResult = validateLoginForm(req.body);
if (!validationResult.success) {
return res.status(400).json({
@@ -103,8 +129,30 @@ router.post('/login', (req, res) => {
});
}

return res.status(200).end();
});

return passport.authenticate('local-login', (err, token, userData) => {
if (err) {
if (err.name === 'IncorrectCredentialsError') {
return res.status(400).json({
success: false,
message: err.message
});
}

return res.status(400).json({
success: false,
message: 'Could not process the form.'
});
}


return res.json({
success: true,
message: 'You have successfully logged in!',
token,
user: userData
});
})(req, res, next);
});

module.exports = router;

This file was deleted.

This file was deleted.