aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDennis Eriksen <dennis.se@gmail.com>2013-04-24 02:27:58 +0200
committerDennis Eriksen <dennis.se@gmail.com>2013-04-24 02:27:58 +0200
commit03b55c108750117206d0178363a3dedf6e1521dc (patch)
tree884eeb5ffa536f06eb5ba4b1fa46cc4f69f646d0
parenttest2 gradient (diff)
downloadDivid-03b55c108750117206d0178363a3dedf6e1521dc.tar.gz
made login work with passport
-rw-r--r--router.js168
-rw-r--r--views/login.ejs8
2 files changed, 169 insertions, 7 deletions
diff --git a/router.js b/router.js
index c63d293..4130ee7 100644
--- a/router.js
+++ b/router.js
@@ -1,8 +1,154 @@
-var passlo = require('./modules/passport-local')
- , passport = require('passport')
- , EM = require('./modules/email-dispatcher');
+var passport = require('passport')
+ , LocalStrategy = require('passport-local').Strategy
+ , mongodb = require('mongodb')
+ , mongoose = require('mongoose')
+ , bcrypt = require('bcrypt')
+ , SALT_WORK_FACTOR = 15;
+
+
+// connects to mongodb
+mongoose.connect('localhost', 'test');
+var db = mongoose.connection;
+db.on('error', console.error.bind(console, 'connection error:'));
+db.once('open', function callback(){
+ console.log('Connected to MongoDB');
+});
+
+// user scheme
+var userSchema = mongoose.Schema({
+ username: { type: String, required: true, unique: true },
+ email: { type: String, required: true, unique: true },
+ password: { type: String, required: true }, //passwords doesn't need to be unique
+ accessToken:{ type: String } // used for Remember Me
+});
+
+// bcrypt middleware
+userSchema.pre('save', function(next) {
+ var user = this;
+
+ if (!user.isModified('password')) return next();
+
+ bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
+ if(err) return next(err);
+
+ bcrypt.hash(user.password, salt, function(err, hash) {
+ user.password = hash;
+ next();
+ });
+ });
+});
+// password verification
+userSchema.methods.comparePassword = function(candidatePassword, cb) {
+ bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
+ if (err) return cb(err);
+ cb(null, isMatch);
+ });
+};
+// remember me implementation
+userSchema.methods.generateRandomToken = function () {
+ var user = this,
+ chars = "_!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
+ token = new Date().getTime() + '_';
+ for (var x = 0; x < SALT_WORK_FACTOR; x++) {
+ var i = Math.floor(Math.random() * 94);
+ token += chars.charAt(i);
+ }
+ return token;
+};
+
+// seed a test user
+var User = mongoose.model('User', userSchema);
+
+var usr = new User({ username: 'bob', email: 'bob@example.com', password: 'secret' });
+usr.save(function(err) {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log('user: ' + usr.username + + 'saved.');
+ }
+})
+
+// Passport session setup.
+// To support persistent login sessions, Passport needs to be able to
+// serialize users into and deserialize users out of the session. Typically,
+// this will be as simple as storing the user ID when serializing, and finding
+// the user by ID when deserializing.
+//
+// Both serializer and deserializer edited for Remember Me functionality
+passport.serializeUser( function(user, done) {
+ var createAccessToken = function() {
+ var token = user.generateRandomToken();
+ User.findOne( { accessToken: token }, function (err, existingUser) {
+ if (err) return done(err);
+ if (existingUser) {
+ createAccessToken(); //run it again. has to be unique
+ } else {
+ user.set('accessToken', token);
+ user.save( function(err) {
+ if (err) return done(err);
+ return done(null, user.get('accessToken'));
+ });
+ }
+ });
+ }
+ if (user._id) { createAccessToken(); }
+});
+
+passport.deserializeUser( function(token, done) {
+ User.findOne( { accessToken: token }, function(err, user) {
+ done(err, user);
+ });
+});
+
+// Use the LocalStrategy within Passport.
+// Strategies in passport require a `verify` function, which accept
+// credentials (in this case, a username and password), and invoke a callback
+// with a user object. In the real world, this would query a database;
+// however, in this example we are using a baked-in set of users.
+/*passport.use(new LocalStrategy(function(username, password, done) {
+ User.findOne({ username: username }, function(err, user) {
+ if (err) return done(err);
+ if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
+ user.comparePassword(password, function(err, isMatch) {
+ if (err) return done(err);
+ if (isMatch) {
+ return done(null, user);
+ } else {
+ return done(null, false, { message: 'Invalid password' });
+ }
+ });
+ });
+}));*/
+
+passport.use(new LocalStrategy(function(username, password, done) {
+ User.findOne({ username: username }, function(err, user) {
+ if (err) { return done(err); }
+ if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
+ user.comparePassword(password, function(err, isMatch) {
+ if (err) return done(err);
+ if(isMatch) {
+ return done(null, user);
+ } else {
+ return done(null, false, { message: 'Invalid password' });
+ }
+ });
+ });
+}));
+
+
+// to ensure that users are logged in
+function ensureAuthenticated(req, res, next) {
+ if (req.isAuthenticated()) return next();
+ res.redirect('/login');
+}
+
+/*
+ * ============================================================
+ * Routes
+ *
+ */
@@ -45,6 +191,7 @@ module.exports = function(app) {
*/
app.get('/dashboard', function(req, res) {
+ ensureAuthenticated();
res.render('dashboard', {
title: 'kanin',
loggedin: true
@@ -81,6 +228,21 @@ module.exports = function(app) {
})(req, res, next);
});
+
+
+ /*
+ * GET logout
+ *
+ * '/logout'
+ */
+ app.post('/logout', function(req, res) {
+ req.logout();
+ res.redirect('/');
+ });
+
+
+
+
/*
* GET project page
*
diff --git a/views/login.ejs b/views/login.ejs
index c0c542d..e3f6e57 100644
--- a/views/login.ejs
+++ b/views/login.ejs
@@ -7,9 +7,9 @@
<h1>Hello!</h1>
<p class="subheading">Please Login To Your Account</p>
<label>Username </label>
- <input type="text" name="user" id="user-tf" class="span4 required">
+ <input type="text" name="username" id="username" class="span4 required">
<label>Password</label>
- <input type="password" name="pass" id="pass-tf" class="span4 required">
+ <input type="password" name="password" id="password" class="span4 required">
<button type="submit" id="btn-login" class="btn btn-primary"><i class="icon-lock icon-white"></i>Sign in</button>
<label id="remember-me" class="checkbox">Remember Me
<input name="remember-me" type="checkbox" checked="checked">
@@ -38,8 +38,8 @@
</div>
<div class="modal-body">
<form method="post" id="get-credentials-form" class="well span5">
- <p>Please enter the email address associated with your account</p>
- <input type="text" name="email" id="email-tf" class="span5 required">
+ <p>Please enter the username associated with your account</p>
+ <input type="text" name="username" id="username" class="span5 required">
<button type="submit" id="submit" class="btn btn-primary">Submit</button>
<button data-dismiss="modal" id="cancel" class="btn">Cancel</button>
<div class="alert alert-error hide"></div>