diff --git a/app.js b/app.js index 63bf0a7..cacdeae 100644 --- a/app.js +++ b/app.js @@ -11,10 +11,13 @@ var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); +// [SH] Require Passport +var passport = require('passport'); // [SH] Bring in the data model require('./app_api/models/db'); -// require('./app_api/config/passport'); +// [SH] Bring in the Passport config after model is defined +require('./app_api/config/passport'); // [SH] Bring in the routes for the API (delete the default routes) @@ -36,6 +39,8 @@ app.use(express.static(path.join(__dirname, 'public'))); // [SH] Set the app_client folder to serve static resources app.use(express.static(path.join(__dirname, 'app_client'))); +// [SH] Initialise Passport before using the route middleware +app.use(passport.initialize()); // [SH] Use the API routes when path starts with /api app.use('/api', routesApi); @@ -56,6 +61,14 @@ app.use(function(req, res, next) { // error handlers +// [SH] Catch unauthorised errors +app.use(function (err, req, res, next) { + if (err.name === 'UnauthorizedError') { + res.status(401); + res.json({"message" : err.name + ": " + err.message}); + } +}); + // development error handler // will print stacktrace if (app.get('env') === 'development') { diff --git a/app_api/config/passport.js b/app_api/config/passport.js index 9f6f794..5d1d6c8 100644 --- a/app_api/config/passport.js +++ b/app_api/config/passport.js @@ -9,16 +9,19 @@ passport.use(new LocalStrategy({ function(username, password, done) { User.findOne({ email: username }, function (err, user) { if (err) { return done(err); } + // Return if user not found in database if (!user) { return done(null, false, { - message: 'Incorrect username.' + message: 'User not found' }); } + // Return if password is wrong if (!user.validPassword(password)) { return done(null, false, { - message: 'Incorrect password.' + message: 'Password is wrong' }); } + // If credentials are correct, return the user object return done(null, user); }); } diff --git a/app_api/controllers/authentication.js b/app_api/controllers/authentication.js index ea472d9..b273c64 100644 --- a/app_api/controllers/authentication.js +++ b/app_api/controllers/authentication.js @@ -9,10 +9,6 @@ var sendJSONresponse = function(res, status, content) { module.exports.register = function(req, res) { console.log("Registering user: " + req.body.email); - res.status(200); - res.json({ - "message" : "User registered: " + req.body.email - }); // if(!req.body.name || !req.body.email || !req.body.password) { // sendJSONresponse(res, 400, { @@ -21,33 +17,26 @@ module.exports.register = function(req, res) { // return; // } - // var user = new User(); + var user = new User(); - // user.name = req.body.name; - // user.email = req.body.email; + user.name = req.body.name; + user.email = req.body.email; - // user.setPassword(req.body.password); + user.setPassword(req.body.password); - // user.save(function(err) { - // var token; - // if (err) { - // sendJSONresponse(res, 404, err); - // } else { - // token = user.generateJwt(); - // sendJSONresponse(res, 200, { - // "token" : token - // }); - // } - // }); + user.save(function(err) { + var token; + token = user.generateJwt(); + res.status(200); + res.json({ + "token" : token + }); + }); }; module.exports.login = function(req, res) { console.log("Logging in user: " + req.body.email); - res.status(200); - res.json({ - "message" : "User logged in: " + req.body.email - }); // if(!req.body.email || !req.body.password) { // sendJSONresponse(res, 400, { @@ -56,22 +45,26 @@ module.exports.login = function(req, res) { // return; // } - // passport.authenticate('local', function(err, user, info){ - // var token; + passport.authenticate('local', function(err, user, info){ + var token; - // if (err) { - // sendJSONresponse(res, 404, err); - // return; - // } + // If Passport throws/catches an error + if (err) { + res.status(404).json(err); + return; + } - // if(user){ - // token = user.generateJwt(); - // sendJSONresponse(res, 200, { - // "token" : token - // }); - // } else { - // sendJSONresponse(res, 401, info); - // } - // })(req, res); + // If a user is found + if(user){ + token = user.generateJwt(); + res.status(200); + res.json({ + "token" : token + }); + } else { + // If user is not found + res.status(401).json(info); + } + })(req, res); }; \ No newline at end of file diff --git a/app_api/controllers/profile.js b/app_api/controllers/profile.js index cf6b263..6373173 100644 --- a/app_api/controllers/profile.js +++ b/app_api/controllers/profile.js @@ -1,24 +1,18 @@ var mongoose = require('mongoose'); var User = mongoose.model('User'); -var sendJSONresponse = function(res, status, content) { - res.status(status); - res.json(content); -}; - - module.exports.profileRead = function(req, res) { - console.log("Reading profile ID: " + req.params.userid); - res.status(200); - res.json({ - "message" : "Profile read: " + req.params.userid - }); -}; -module.exports.profileUpdate = function(req, res) { - console.log("Updating profile ID: " + req.params.userid); - res.status(200); - res.json({ - "message" : "Profile updated for " + req.params.userid - }); + if (!req.payload._id) { + res.status(401).json({ + "message" : "UnauthorizedError: private profile" + }); + } else { + User + .findById(req.params.userid) + .exec(function(err, user) { + res.status(200).json(user); + }); + } + }; diff --git a/app_api/models/users.js b/app_api/models/users.js index 646bab2..2995881 100644 --- a/app_api/models/users.js +++ b/app_api/models/users.js @@ -1,6 +1,6 @@ var mongoose = require( 'mongoose' ); -// var crypto = require('crypto'); -// var jwt = require('jsonwebtoken'); +var crypto = require('crypto'); +var jwt = require('jsonwebtoken'); var userSchema = new mongoose.Schema({ email: { @@ -16,26 +16,26 @@ var userSchema = new mongoose.Schema({ salt: String }); -// userSchema.methods.setPassword = function(password){ -// this.salt = crypto.randomBytes(16).toString('hex'); -// this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).toString('hex'); -// }; +userSchema.methods.setPassword = function(password){ + this.salt = crypto.randomBytes(16).toString('hex'); + this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).toString('hex'); +}; -// userSchema.methods.validPassword = function(password) { -// var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).toString('hex'); -// return this.hash === hash; -// }; +userSchema.methods.validPassword = function(password) { + var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64).toString('hex'); + return this.hash === hash; +}; -// userSchema.methods.generateJwt = function() { -// var expiry = new Date(); -// expiry.setDate(expiry.getDate() + 7); +userSchema.methods.generateJwt = function() { + var expiry = new Date(); + expiry.setDate(expiry.getDate() + 7); -// return jwt.sign({ -// _id: this._id, -// email: this.email, -// name: this.name, -// exp: parseInt(expiry.getTime() / 1000), -// }, process.env.JWT_SECRET); // DO NOT KEEP YOUR SECRET IN THE CODE! -// }; + return jwt.sign({ + _id: this._id, + email: this.email, + name: this.name, + exp: parseInt(expiry.getTime() / 1000), + }, "MY_SECRET"); // DO NOT KEEP YOUR SECRET IN THE CODE! +}; mongoose.model('User', userSchema); diff --git a/app_api/routes/index.js b/app_api/routes/index.js index 60e29f4..dd83d02 100644 --- a/app_api/routes/index.js +++ b/app_api/routes/index.js @@ -1,17 +1,16 @@ var express = require('express'); var router = express.Router(); -// var jwt = require('express-jwt'); -// var auth = jwt({ -// secret: process.env.JWT_SECRET, -// userProperty: 'payload' -// }); +var jwt = require('express-jwt'); +var auth = jwt({ + secret: process.env.JWT_SECRET, + userProperty: 'payload' +}); var ctrlProfile = require('../controllers/profile'); var ctrlAuth = require('../controllers/authentication'); // profile -router.get('/profile/:userid', ctrlProfile.profileRead); -router.put('/profile/:userid', ctrlProfile.profileUpdate); +router.get('/profile/:userid', auth, ctrlProfile.profileRead); // authentication router.post('/register', ctrlAuth.register); diff --git a/app_client/auth/login/login.controller.js b/app_client/auth/login/login.controller.js index 8249331..e9d439a 100644 --- a/app_client/auth/login/login.controller.js +++ b/app_client/auth/login/login.controller.js @@ -8,10 +8,6 @@ function loginCtrl($location) { var vm = this; - // vm.pageHeader = { - // title: 'Sign in to Loc8r' - // }; - // vm.credentials = { // email : "", // password : "" diff --git a/app_client/common/services/authentication.service.js b/app_client/common/services/authentication.service.js new file mode 100644 index 0000000..33e5ba8 --- /dev/null +++ b/app_client/common/services/authentication.service.js @@ -0,0 +1,74 @@ +(function () { + + angular + .module('meanApp') + .service('authentication', authentication); + + authentication.$inject = ['$http', '$window']; + function authentication ($http, $window) { + + var saveToken = function (token) { + $window.localStorage['mean-token'] = token; + }; + + var getToken = function () { + return $window.localStorage['mean-token']; + }; + + var isLoggedIn = function() { + var token = getToken(); + var payload; + + if(token){ + payload = token.split('.')[1]; + payload = $window.atob(payload); + payload = JSON.parse(payload); + + return payload.exp > Date.now() / 1000; + } else { + return false; + } + }; + + var currentUser = function() { + if(isLoggedIn()){ + var token = getToken(); + var payload = token.split('.')[1]; + payload = $window.atob(payload); + payload = JSON.parse(payload); + return { + email : payload.email, + name : payload.name + }; + } + }; + + register = function(user) { + return $http.post('/api/register', user).success(function(data){ + saveToken(data.token); + }); + }; + + login = function(user) { + return $http.post('/api/login', user).success(function(data) { + saveToken(data.token); + }); + }; + + logout = function() { + $window.localStorage.removeItem('mean-token'); + }; + + return { + currentUser : currentUser, + saveToken : saveToken, + getToken : getToken, + isLoggedIn : isLoggedIn, + register : register, + login : login, + logout : logout + }; + } + + +})(); \ No newline at end of file diff --git a/app_client/profile/profile.view.html b/app_client/profile/profile.view.html index ce08da6..319f628 100644 --- a/app_client/profile/profile.view.html +++ b/app_client/profile/profile.view.html @@ -5,23 +5,19 @@
Update your profile here
- - -