aboutsummaryrefslogblamecommitdiffstatshomepage
path: root/router.js
blob: 0750bdf2b350231037d30d644a24ebfe042ee49a (plain) (tree)
1
2
3

                                                      
                                                            



























































                                                                                       
  






                                                                                      
    























                                                                                
                                    
                                          
                              


                                                 





                                                                   






                                                                               
                                                                   











                                                                                         
    
 




                                                                          


                                               











                                                                                  
 

                                              
                                                    








                                                               










                                    
                                               

       






                                         



                            

       






                                         

      




                    
                                              
                                                
                                 


                                                       




       





                                          
                                                       


       

              






                                                                  
             




                                                  

       




















                                                                                                                             






                 
                                           
                     
                              




       





                       


                                                                    


 

 
      









                                                         




















                                            
 
      
             

       
             
                                     
                                                                       

       



                                                                                           

 
  
var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy
  , FacebookStrategy = require('passport-facebook').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'));
                });
            }
        });
    }
    console.log('serializing user');
    if (user._id) { createAccessToken(); }
    else { done(null, user); }
});

passport.deserializeUser( function(token, done) {
    console.log('deserializing ' + token.provider);
    if (token.provider === undefined) {
        User.findOne( { accessToken: token }, function(err, user) {
            done(err, user);
        });
    } else { done(null, token); }
});

// 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' });
            }
        });
    });
}));

// Use the FacebookStrategy within Passport.
//   Strategies in Passport require a `verify` function, which accept
//   credentials (in this case, an accessToken, refreshToken, and Facebook
//   profile), and invoke a callback with a user object.
passport.use(new FacebookStrategy({
    clientID: config.facebook.clientID,
    clientSecret: config.facebook.clientSecret,
    callbackURL: config.facebook.callbackURL
}, function(accessToken, refreshToken, profile, done) {
    // asynchronous verification, for effect...
    process.nextTick(function() {

        // To keep the example simple, the user's Facebook profile is returned to
        // represent the logged-in user.  In a typical application, you would want
        // to associate the Facebook account with a user record in your database,
        // and return that user instead.
        return done(null, profile);
    });
  }
));

// to ensure that users are logged in
function ensureAuthenticated(req, res, next) {
    console.log('checking to see if authenticated');
    if (req.isAuthenticated()) return next();
    res.redirect('/login');
}

/*
 * ============================================================
 * Routes
 *
 */



module.exports = function(app) {
    /*
     * GET home page.
     *
     * '/'
     */

    app.get('/', function(req, res){
        res.render('index', { title: 'DERS' });
    });

    /*
     * GET TEST PAGE
     *
     * '/test'
     */

    app.get('/test', function(req, res) {
        res.render('test', {
            title: 'test',
            loggedin: false
        });
    });

    app.get('/home', function(req, res) {
        res.render('home', {
            title: 'home',
            loggedin: false
        });
    });


    /*
     * GET dashboard
     *
     * '/dashboard'
     */

    app.get('/dashboard', function(req, res) {
        console.log('/dashboard - ' + req.user);
        res.render('dashboard', {
                                        title: 'kanin',
                                        loggedin: true
                                    });
    });



    /*
     * GET login page
     *
     * '/login'
     */

    app.get('/login', function(req, res) {
            res.render('login', { title: 'Logg inn' });
    });


    /* POST */

    app.post('/login', function(req, res, next) {
        passport.authenticate('local', function(err, user, info) {
            if (err) return next(err);
            if (!user) {
                console.log(info.message);
                req.session.messages = [info.message];
                return res.redirect('/login');
            }
            req.logIn(user, function(err) {
                if (err) return next(err);
                return res.redirect('/dashboard');
            })
        })(req, res, next);
    });

    // GET /auth/facebook
    //   Use passport.authenticate() as route middleware to authenticate the
    //   request.  The first step in Facebook authentication will involve
    //   redirecting the user to facebook.com.  After authorization, Facebook will
    //   redirect the user back to this application at /auth/facebook/callback
    app.get('/auth/facebook', passport.authenticate('facebook'), function(req, res){
        // The request will be redirected to Facebook for authentication, so this
        // function will not be called.
    });

    // GET /auth/facebook/callback
    //   Use passport.authenticate() as route middleware to authenticate the
    //   request.  If authentication fails, the user will be redirected back to the
    //   login page.  Otherwise, the primary route function function will be called,
    //   which, in this example, will redirect the user to the home page.
    app.get('/auth/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/login' }), function(req, res) {
        console.log('/auth/facebook/callback --- ' + req.user.username);
        res.redirect('/dashboard');
    });




    /*
     * GET logout
     *
     * '/logout'
     */
    app.get('/logout', function(req, res) {
        req.logout();
        res.redirect('/test');
    });




    /*
     * GET project page
     *
     * '/project'
    */

    app.get('/project', function(req, res) {
        res.render('project', { title: 'Harepus', loggedin: true });
    })





    /*
     * GET signup page
     *
     * '/signup'
     */

    app.get('/signup', function(req, res) {
        res.render('signup', { title: 'Registrer deg' });
    });


    /* POST */

    app.post('/signup', function(req, res) {
        AM.addNewAccount({
            name    : req.param('name'),
            email   : req.param('email'),
            user    : req.param('user'),
            pass    : req.param('pass'),
            country : req.param('country')
        }, function(e) {
            if (e) {
                res.send(e, 400);
            } else {
                res.send('ok', 200);
            }
        });
    });





    /*
     * ERRORS
     */

    /* 404 */
    app.get('*', function(req, res) {
        res.render('error', { title: '404', text: 'Fant ikke siden' });
    });

    /* 403 on POST */
    app.post('*', function(req, res) {
        res.render('error', { title: '403', text: 'Du har ikke tilgang til denne siden' });
    });


};