WebFund 2014W: Assignment 2

From Soma-notes
Revision as of 15:54, 5 February 2014 by Soma (talk | contribs) (→‎Source)

This assignment is not yet finalized

In this assignment you are to examine, modify, and answer questions regarding the adventure-demo sample node application. The files of this application are also listed below. Note that to run this application you'll first need to run node storeRooms.js to setup the rooms collection in MongoDB.

Please submit your answers as a single zip file called "<username>-comp2406-assign2.zip" (where username is your MyCarletonOne username). This zip file should unpack into a directory of the same name (minus the .zip extension of course). This directory should contain:

  • your modified version of adventure-demo (one version with all code changes) and
  • a text file called "answers.txt" or "answers.pdf" at the top level (in text or PDF format, respectively) that contains the answers to the all of the questions, with the first four lines being "COMP 2406 Assignment 2", your name, student number, and the date. For questions requiring code changes (Part B), explain in your answers file which parts of the program were changed. You may wish to format answers.txt in Markdown to improve its appearance.

No other formats will be accepted. Submitting in another format will likely result in your assignment not being graded and you receiving no marks for this assignment. In particular do not submit an MS Word or OpenOffice file as your answers document!

Questions

There are ?? points below in three parts. Answer all questions.

Part A

What happens when you change the following lines in adventure-demo? Describe the change in behaviour as if each deletion is the only change made to the application. If a runtime error is generated please describe the error and briefly explain why that error was produced. (two points each, ?? total)

Part B

Describe how to change the code to add the following features/change the following behaviour. If the changes are small, specify the line(s) to changed. If the changes are more substantial, you may just list the entire modified file. These changes are cumulative, so the changes for the third question should take into account those made previously.

  1. How can you change this app to list all of the currently logged in users on /users?

Part C

  1. (5 points) What is the difference between the Login and Register button on the initial screen? Do they work the same way?
  2. (4 points) MongoDB's "tables" are collections; they are grouped together into databases. What MongoDB database is used by this application? What collections?
  3. (2 points) How long before this app's session cookies expire? How do you know?
  4. (4 points) Do sessions and user accounts persist across web application restarts? Why or why not?
  5. (4 points) In the POST function for /start, it processes a username and password supplied by the user. What object stores this information in node for our program to access? What line in app.js loads the code to provides the values for this object?
  6. (4 points) Why are there three arguments to the app.get()'s, rather than the previous two? What does the third argument do?
  7. The routes.register() has multiple nested functions. What do each of them do, and why are they nested the way they are?

Source

app.js

/**
 * Module dependencies.
 */

var express = require('express');
var routes = require('./routes');
var path = require('path');
var fs = require('fs');

var http = require('https');  // note https, not http!
var MongoStore = require('connect-mongo')(express);

var app = express();

var options = {
  key: fs.readFileSync('keys/comp2406-private-key.pem'),
  cert: fs.readFileSync('keys/comp2406-cert.pem')
};

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());

app.use(express.cookieParser('COMP 2406 adventure demo!'));
app.use(express.session({
    cookie: {maxAge: 60000 * 20} // 20 minutes
    , secret: "Shh... I'm a secret"
    , store: new MongoStore({db: "adventure-demo"})
}));

app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// set NODE_ENV environment variable to change from development mode
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.redirectLoggedIn, routes.index);
app.post("/register", routes.register);
app.post("/start", routes.start);
app.post("/quit", routes.quit);

var createRooms = function() {
    var i, theRoom;

    routes.getRooms().toArray(
	function(err, docs) {
	    if (err) {
		throw "Couldn't find active room list";
	    }
	    
	    var activeRooms = docs[0].activeRooms;

	    activeRooms.forEach(function(roomName) {
		console.log('Creating room: ' + roomName);
		app.get('/' + roomName,
			routes.makeRoomHandler(roomName));
	    });
	}
    );
}
routes.connectToDBs(createRooms);

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


storeRooms.js

// storeRooms.js

var mc = require('mongodb').MongoClient;

var rooms = [
    
    {
	name: "roomList",
	activeRooms: ['bridge', 'sickbay', 'engineering']
    },
    {   name: "bridge",
	title: "Bridge",
	description: "You are on the Bridge.  There are big comfy chairs and a big screen here.",
	roomExits: ['sickbay'],
    },    
    {
	name: "engineering",
	title: "Engineering",
	description: "You are in Engineering.  There are lots of funny instruments, many smaller screens, and kind of uncomfortable chairs.",
	roomExits: ['sickbay'],
    },

    {
	name: "sickbay",
	title: "Sickbay",
	description: "You are in Sickbay.  It is in the center of the ship, the safest place there is.  There are lots of comfy beds here and blinky lights.",
	roomExits: ['engineering','bridge'],
    },

    {
	name: "secret",
	title: "Secret Room",
	description: "This is a secret room.  How did you get here?",
	roomExits: ['engineering', 'sickbay', 'bridge'],
    },
];

mc.connect('mongodb://localhost/adventure-demo', function(err, db) {
    if (err) {
	throw err;
    }
    
    var roomsCollection = db.collection('rooms');

    roomsCollection.drop(function(err, count) {
	if (err) {
	    console.log("No collection to drop.");
	} else {
	    console.log("room collection dropped.");
	}
	roomsCollection.insert(rooms, function(err, rooms) {
	    if (err) {
		throw err;
	    }

	    rooms.forEach(function(room) {
		console.log("Added " + room.name);
	    });
	    db.close();
	});
    });
});