WebFund 2013W Lecture 23

From Soma-notes
Revision as of 16:18, 9 April 2013 by Soma (talk | contribs)

The final exam will be similar to the midterm. To prepare, make sure you understand the content on the midterm and understand the code and questions below.

Questions

Note: these are just a sample of the kinds of questions that will be on the final.



Code

demo-auth-hash/app.js

/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path')
  , bcrypt = require("bcrypt") //hashing algorithm
  , MongoStore = require('connect-mongo')(express) //session datastore using mongodb
  , mongoose = require('mongoose') //blessed mongodb connector
  , User; //User class defined below

//connect to the "users" database
mongoose.connect('mongodb://localhost/users');
var db = mongoose.connection;

db.on('error', console.error.bind(console, 'connection error:'));

//once the DB connection is open...
db.once('open', function callback () {
        //Create a mongoose Schema (document structure)
  var userSchema = mongoose.Schema({
                username: String,
                password: String
        });
        
        //Convert this schema into an instantiable "model" Class 
        User = mongoose.model("User", userSchema);
});


  
var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  
  //enable cookies
  app.use(express.cookieParser());
  
  //setup session management
  app.use(express.session({
                  cookie: {maxAge: 60000 * 20} // 20 minutes
                , secret: "Shh... I'm a secret"
                , store: new MongoStore({ //use a mongo-connect store
      db: "sessions" 
    })
        }));
        
  app.use(app.router);
  app.use(require('less-middleware')({ src: __dirname + '/public' }));
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', function(req, res, next){
    //redirect to user page if logged in
    if(req.session.username){
        res.redirect("/users");
    }else{
        next();
    }
}, routes.index);
app.get('/users', function(req, res, next){
    //redirect home if not logged in
    if(req.session.username){
        next();
    }else{
        res.redirect("/");
    }
}, user.list);

app.post("/register", function(req, res){
        var username = req.body.username;
        var password = req.body.password;
        User.find({username: username}, function(err, users){
          //check if the user already exists
          if(users.length!=0){
                  res.redirect("/?error=user already exists");  
                  return;
          }
          //generate a salt, with 10 rounds (2^10 iterations)
          bcrypt.genSalt(10, function(err, salt) {
                  //hash the given password using the salt we generated
      bcrypt.hash(password, salt, function(err, hash) {
        //create a new instance of the mongoose User model we defined above
        var newUser = new User({
                username: username,
                password: hash
        });     
        
        //save() is a magic function from mongoose that saves this user to our DB
        newUser.save(function(err, newUser){
                res.send("successfully registered user: "+newUser.username);
        });    
      });
          });   
        });     
});

app.post("/login", function(req, res){
        var username = req.body.username;
        var password = req.body.password;
        //Search the Database for a User with the given username
        User.find({username: username}, function(err, users){
                //we couldn't find a user with that name
                if(err || users.length==0){
                        res.redirect("/?error=invalid username or password");   
                        return;
                }
                
                var user = users[0];
                //compare the hash we have for the user with what this password hashes to
                bcrypt.compare(password, user.password, function(err, authenticated){
                        if(authenticated){
                                req.session.username = user.username;
                                res.redirect("/users");
                        }else{
                                res.redirect("/?error=invalid username or password");   
                        }
                });
        });
});

app.post("/logout", function(req, res){
        req.session.destroy(function(err){
      if(err){
          console.log("Error: %s", err);
      }
      res.redirect("/");
  });   
});

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

demo-auth-hash/views/layout.jade

doctype 5
html
  head
    title= title
    script(src='/libs/jquery/jquery.min.js')
    script(src='/src/home.js')
    link(rel='stylesheet', href='/libs/bootstrap/css/bootstrap.min.css')
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content

demo-auth-hash/views/index.jade

extends layout

block content
  h1= title
  p Welcome to #{title}
  - if(error)
    div.alert-error #{error}
  p Please log in
  div
    form(action="/login", method="post")
        div.control-group.input-append
            input(type="text", name="username")
            label.add-on(for="username") Username
        div.control-group.input-append
            input(type="password", name="password")
            label.add-on(for="password") Password
            
        button(type="submit") Login
        button#register(type="button") Register

blog-updated/articleprovider-mongodb.js

var Db = require('mongodb').Db;
var Connection = require('mongodb').Connection;
var Server = require('mongodb').Server;
var BSON = require('mongodb').BSON;
var ObjectID = require('mongodb').ObjectID;

ArticleProvider = function(host, port) {
    this.db= new Db('node-mongo-blog', new Server(host, port, {auto_reconnect: true}), {journal: true});
  this.db.open(function(){});
};

//addCommentToArticle

ArticleProvider.prototype.addCommentToArticle = function(articleId, comment, callback) {
  this.getCollection(function(error, article_collection) {
    if( error ) callback( error );
    else {
      article_collection.update(
        {_id: article_collection.db.bson_serializer.ObjectID.createFromHexString(articleId)},
        {"$push": {comments: comment}},
        function(error, article){
          if( error ) callback(error);
          else callback(null, article)
        });
    }
  });
};

//getCollection

ArticleProvider.prototype.getCollection= function(callback) {
  this.db.collection('articles', function(error, article_collection) {
    if( error ) callback(error);
    else callback(null, article_collection);
  });
};

//findAll
ArticleProvider.prototype.findAll = function(callback) {
    this.getCollection(function(error, article_collection) {
      if( error ) callback(error)
      else {
        article_collection.find().toArray(function(error, results) {
          if( error ) callback(error)
          else callback(null, results)
        });
      }
    });
};

//findById

ArticleProvider.prototype.findById = function(id, callback) {
    this.getCollection(function(error, article_collection) {
      if( error ) callback(error)
      else {
        article_collection.findOne({_id: article_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
          if( error ) callback(error)
          else callback(null, result)
        });
      }
    });
};

//save
ArticleProvider.prototype.save = function(articles, callback) {
    this.getCollection(function(error, article_collection) {
      if( error ) callback(error)
      else {
        if( typeof(articles.length)=="undefined")
          articles = [articles];

        for( var i =0;i< articles.length;i++ ) {
          article = articles[i];
          article.created_at = new Date();
          if( article.comments === undefined ) article.comments = [];
          for(var j =0;j< article.comments.length; j++) {
            article.comments[j].created_at = new Date();
          }
        }

        article_collection.insert(articles, function() {
          callback(null, articles);
        });
      }
    });
};

exports.ArticleProvider = ArticleProvider;