text: // ========================
  // get the packages we need
  // ========================
  var express     = require('express');
  var app         = express();
  var bodyParser  = require('body-parser');
  var morgan      = require('morgan');
  var mongoose    = require('mongoose');
  
  var jwt     = require('jsonwebtoken');  // used to create, sign and verify tokens
  var config  = require('./config'); // get our config file
  var User    = require('./app/models/user'); // get our mongoose model
  
  // ==============
  // initialization
  // ==============
  var port = process.env.PORT || 3000;
  mongoose.connect(config.database);
  app.set('superSecret', config.secret);
  
  // use body parser so we can get info from POST and/or URL parameters
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use(bodyParser.json());
  
  // use morgan to log requests to the console
  app.use(morgan('dev'));
  
  // ======
  // routes
  // ======
  // basic route
  app.get('/', function(req, res) {
    res.send('Hello! The API is at http://localhost:' + port + '/api');
  });
  
  // API routes
  
  // for dev only
  app.get('/setup', function(req, res) {
    // create a sample user
    var nick = new User({
      name: 'Nick Cerminara',
      password: 'password',
      admin: true
    });
  
    // save the sample user
    nick.save(function(err) {
      if (err) throw err;
  
      console.log('User saved successfully');
      res.json({ success: true });
    });
  });
  
  // get an instance of the router for api routes
  var apiRoutes = express.Router();
  
  // route to authenticate a user (POST http://localhost:3000/api/authenticate)
  apiRoutes.post('/authenticate', function(req, res) {
    // find the user
    User.findOne({
      name: req.body.name
    }, function(err, user) {
      if (err) throw err;
  
      if (!user) {
        res.json({ success: false, message: 'Authentication failed. User not found.' });
      } else if (user) {
        // check if password matches
        if (user.password != req.body.password) {
          res.json({ success: false, message: 'Authentication failed. Wrong password.' });
        } else {
          // if user is found and password is right
          // create a token
          var token = jwt.sign(user, app.get('superSecret'), {
            expiresIn: '1d' // expires in 24 hours
          });
  
          // return the information including token as JSON
          res.json({
            success: true,
            message: 'Enjoy your token!',
            token: token
          });
        }
      }
    });
  });
  
  // route middleware to verify a token
  apiRoutes.use(function(req, res, next) {
    // check header or url parameters or post parameters for token
    var token = req.body.token || req.query.token || req.headers['x-access-token'];
  
    // decode token
    if (token) {
      // verifies secret and checks exp
      jwt.verify(token, app.get('superSecret'), function(err, decoded) {
        if (err) {
          return res.json({ success: false, message: 'Failed to authenticate token' });
        } else {
          // if everything is good, save to request for use in other routes
          req.decoded = decoded;
          next();
        }
      });
    } else {
      // if there is no token, return an error
      return res.status(403).send({
        success: false,
        message: 'No token provided.'
      });
    }
  });
  
  // route to show a random message (GET http://localhost:3000/api/)
  apiRoutes.get('/', function(req, res) {
    res.json({ message: 'Welcome to the coolest API on Earth!' });
  });
  
  // route to return all users (GET http://localhost:3000/api/users)
  apiRoutes.get('/users', function(req, res) {
    User.find({}, function(err, users) {
      if (err) throw err;
  
      res.json(users);
    });
  });
  
  // apply the routes to our application with the prefix /api
  app.use('/api', apiRoutes);
  
  // ================
  // start the server
  // ================
  app.listen(port);
  console.log('Magic happens at http://localhost:' + port);