Skip to content
Brian Soe edited this page Apr 14, 2016 · 60 revisions

COGS 121 - Assignment 1

Due: Monday 4/18, 11:59pm

(1-point extra credit if turned in prior to Thursday 4/14, 12:00pm)

The purpose of this assignment is to get familiar with basics of OAuth 2.0 using Passport.js (specifically Twitter), web socket using Socket.io, and integrate software tools to create a social media application. This assignment is divided into two parts: (1) technical lab for Passport.js and Socket.io, and (2) designing a social media application. By the end of this assignment, students comfortable at using Passport.js and Socket.io and design more powerful software with these tools. This is a group-based assignment and you need to work on it within your assigned team (4-5 people).

Note

  • This assignment is intended to be done in a group.
  • The assignment may feel overwhelming, so please start early and collaborate with your group!
  • The given boilerplate is broken (intentionally). It is your responsibility to fix it.
  • We expect that you have completed assignment 0. Any resources you used for assignment 0 are fair game.
  • Only Part 2 will be graded. However, since Part 1 provides guidances to Part 2, it is important that you complete Part 1 as well.
  • DO NOT PUSH OR SEND PULL REQUEST TO BOILERPLATE REPOSITORY

Goal:

  • Utilize knowledge from assignment 0 for more complex tools.
  • Understand basics of OAuth 2.0 and web socket.
  • Utilize Passport.js and Socket.io to create a social media application.

Before Starting

What is an OAuth 2.0? What is a web socket? Why do we need them? Before you jump into the coding portion of this assignment, it is important to understand the high-level concepts of these technical terms. We have provided some resources as an introduction to both OAuth 2.0 and web socket.

For this assignment, we will be using OAuth 2.0 as a way to manage personalized profiles of a user and web socket as live communication between users. Both are essential for most social media application nowadays.

The Assignment (Part 1.1) - Preparation

Part 1 of Assignment 1 will be an exercise to help you create a simple social media application with specific tasks. In Part 2 (as mentioned above), you will be creating your own social media application using the skills you acquired in Part 1. Again, Part 1 will not be graded (explicitly), but is a crucial component to do Part 2. The expected result for Part 1 should work similarly to this example app.

Fork and Clone: Fork this repository and clone it to grab the boilerplate code for assignment 1 (you do not need to use your files from assignment 0)

Part 1.1 consists of preparation steps before dealing with the main meat of this assignment. It is important that you understand how the following files work before starting Assignment 1: server.js, views/layouts/layout.html, views/index.html, views/chat.html, and public/js/chatbox.js. You may use Piazza, and other online resources to solve your problem(s).

  1. Install the following Node.js dependencies: connect-mongo (1.1.0), cookie-parser (1.4.1), dotenv (2.0.0), express-session (1.13.0), method-override (2.3.5), passport (0.3.2), passport-twitter (1.0.4), socket.io (1.4.5)

    • You may refer to Assignment 0 to install these dependencies
    • Also install dependencies from Assignment 0
    • Don't forget to create the directories needed for the database
  2. Create your application on Twitter (Twitter Apps Site)

  3. Store Consumer Key (API Key) and Consumer Secret (API Secret) to .env file

    • Create a file called .env at the root directory of your project.
    • Copy and paste the Consumer Key and Consumer Secret given to you by Twitter (from step 2).
    • This information is sensitive and SHOULD NOT BE SHARED WITH ANYONE ELSE!
      • This means .env or any file that contains API Key and API Secret should not be in your Github repository.
    • Your .env file should look similar to following:
    TWITTER_CONSUMER_KEY=<your consumer key here in quotes>
    TWITTER_CONSUMER_SECRET=<your consumer secret here in quotes>
    SESSION_SECRET="4fa238c5d0d632881b6786f3b2d944950169948f"
    
    • Make sure dotenv is loaded in server.js
    • Resource: npm dotenv site
    • Note that the SESSION_SECRET is static and will be the same for all applications
  4. Uncomment following code:

    app.get("/", router.index.view);
    

The Assignment (Part 1.2) - Passport.js

Part 1.2 focuses on how to get started with Passport.js, specifically with Passport-Twitter. These tools will help you manage user authentication and Twitter OAuth for Node.js. Keep in mind that Passport.js provides authentication methods beyond Twitter (such as creating secure local login feature or other social media OAuth). To keep things simple for this practice, we will only use the Twitter component of Passport.js. You may use other authentication methods for Part 2. You may use passportjs docs, Piazza, and other online resources to solve your problem(s).

  1. Set your Passport middleware in server.js

    • The middleware code for Passport is shown below. Copy and paste them to appropriate place.
    app.use(passport.initialize());
    app.use(passport.session());
    
    • What is middleware?
      • Most of the middleware codes for this assignment are handled in the given boilerplate.
      • Understanding the middleware is beyond the purpose of this course, so do not worry if you do not fully understand.
      • To learn more about Express's middleware: read this guide on using express middleware
    • Note that for middleware code, the order in which middleware is included is very important. For example, try placing the Passport middleware code in random spots throughout the file and running the server. What happens? (most likely an error or unexpected behavior)
  2. Set your Passport serialization in server.js

    • The serialization code for Passport is shown below. Copy and paste them to the appropriate place.
    passport.serializeUser(function(user, done) {
        done(null, user);
    });
    passport.deserializeUser(function(user, done) {
        done(null, user);
    });
    
  3. Use Twitter strategy in server.js

    passport.use(new strategy.Twitter({
        consumerKey: process.env.TWITTER_CONSUMER_KEY,
        consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
        callbackURL: "/auth/twitter/callback"
    }, function(token, token_secret, profile, done) {
        // What goes here? Refer to step 4.
    });
    
  4. Write targeted code to check if a user already exists within your application.

    • The documentation for Passport-Twitter may use findOrCreate() function from models (mongoose/MongoDB) to check if user exists or not (if not, then create the user).
    • For this assignment, we will be using findOne() function instead.
    • Resource: stackoverflow
    • The skeleton code for this step is:
    models.User.findOne({ "twitterID": profile.id }, function(err, user) {
        // (1) Check if there is an error. If so, return done(err);
        if(!user) {
            // (2) since the user is not found, create new user.
            // Refer to Assignment 0 to how create a new instance of a model
            return done(null, profile);
        } else {
            // (3) since the user is found, update user’s information
            process.nextTick(function() {
                return done(null, profile);
            });
        }
      });
    
  5. Create routes for authentication

    • Again, refer to passportjs twitter docs to understand how routing for Twitter authentication works.
    • You may also want to read passportjs logout docs to create a route for logging a user out.
    • Create routes with following spec:
      • "/auth/twitter" - GET Request
      • "/auth/twitter/callback" - GET Request (success redirect: "/chat" and failure redirect: "/")
      • "/logout" - GET Request
  6. Create UserSchema in models.js

    • The model for User will have (at minimum) following schema:
    {
        "twitterID": String,
        "token": String,
        "username": String,
        "displayName": String,
        "photo": String
    }
    
    • Refer to Assignment 0 for creating a schema(s) in models.js
  7. Before you move on, make sure you don't encounter any errors when executing.

    • Again, this is bound to happen since given code is intentionally broken.
    • If you see any errors, it is your responsibility to fix them.
    • NOTE: For the functionality of "/chat" route, make sure that it redirects to "/" if user has not been authenticated.

The Assignment (Part 1.3) - Socket.io

Part 1.3 will help you experiment with Socket.io. This tool allows you handle live message delivery (live communication between users). One very simple use case of this tool is a chat system. For part 1, we will implement a very basic chat system that is public (private is a bit more complicated, feel free to look into that on your own time ). You may use socket.io docs, Piazza, and other online resources to solve your problem(s).

  1. Read and understand: socket.io chat docs.

    • We recommend that you also try this tutorial out (preferably on a separate project).
    • If you do not understand how this tutorial works, please ask before moving on.
  2. Uncomment the following code in server.js:

    io.use(function(socket, next) {
        session_middleware(socket.request, {}, next);
    });
    
  3. Create a socket "connection" on public/js/chatbox.js (client-side)

    • Your solution for this step should be written in a TODO section of public/js/chatbox.js file.
    • Hint: start with var socket = io(); which will create a web socket on the client-side.
    • Grab the text from #user_input upon the user submitting the form.
    • Make sure that the text in #user_input is cleared.
  4. Create a socket "connection" on server.js (server-side)

    • Hint: start with io.on("connection", function(socket) { ... }); which will handle receiving socket request from client.
  5. Create a socket called "newsfeed" on both public/js/chatbox.js and server.js

    • Add the following code to public/js/chatbox.js:
    socket.on("newsfeed", function(data) {
        var parsedData;
        // grab and parse data and assign it to the parsedData variable.
    
        // other possible solution(s) here.
        $('#messages').prepend($('<li>').html(messageTemplate(parsedData)));
    
        function messageTemplate(parsedData) {
          // generate HTML text based on some data to be prepended into the list
        }
    });
    
    • For server.js, you may create a socket for "newsfeed" with following skeleton code:
    socket.on("newsfeed", function(msg) {
        ...
        // your solution to fill in, see step 7 for details
        ...
        io.emit("newsfeed", ...);
        ...
    });
    
  6. Create NewsFeedSchema in models.js

    • The model for NewsFeed will have (at minimum) following schema:
    {
        "user": String,
        "message": String,
        "posted": Date
    }
    
    • Refer to Assignment 0 for creating a schema(s) in models.js
  7. Create the following functionality in server.js:

    • Upon receiving request through "newsfeed" socket, create a new instance of NewsFeed model and save it to the database.
    • The middleware code given in the boilerplate allows you to use socket.request.session.passport.user to access Passport's user information.
      • This will grab the currently authenticated user in a given "session"
      • If there are no authenticated user in that session, then this may throw an error.
      • You may use try-catch techniques to handle this error: w3schools try catch resource.
    • You may also find JSON.stringify(...) and/or JSON.parse(...) helpful.
  8. Before you move on, make sure you don't encounter any errors when executing the code.

    • Again, this is bound to happen since given code is intentionally broken.
    • If you see any errors, it is your responsibility to fix them.
    • Tip: Check through all the files to see if there are any more "TODO" comments

NOTE: If you wish to push Part 1 to Heroku, please refer to step 6 of Part 2.

The Assignment (Part 2) - Create your own social media app

Now that you have gained the technical skills essential for interacting with social media, it is your turn to make your own! In Part 2, you will pick a theme/user audience for your social media. Then, create a small-scale social media application that will improve social interaction for that user audience. Unless specified, there are no restrictions for creating your application. Keep in mind, this is a group assignment; everyone should collaborate and contribute to create a well-designed application.

  1. Pick a theme and/or a group of user audiences

    • Here are examples of a theme (your theme are not limited to these examples):
      • a communication tool for academic researchers to share their research papers.
      • a communication tool to gather all accountants around the world and share their tips.
      • an application for rock climbers to share experiences of and ratings for climbing routes
      • an application for designers/developers to share and discover works in progress
  2. Create a way for your user audiences to communicate

    • Again, you are not required to create a mechanism for private communication (either 1-to-1 or group).
    • However, if you feel comfortable and feel that private communication is necessary, you may choose to do so.
  3. Required technologies: Node.js, MongoDB, Passport.js, and Socket.io

    • You may use other technologies in addition to technologies listed above to facilitate development process
    • You may use local login authentication and/or OAuth 2.0 services such as Twitter, Facebook, Instagram, etc.
    • It is your responsibility to handle any technical constraints that are not mentioned in Part 1.
      • So choose an approach that is most comfortable and beneficial for you.
  4. Apply Nielsen's Heuristics

    • Refer to course reading materials and lecture slides
    • Also: 10 usability heuristics reference
    • This means, you should also implement codes for HTML, CSS, and Javascript as well.
    • Any violation of a heuristic may result deduction of your grade.
    • On your README, please provide a sentence description for each heuristic addressed in your application.
  5. Document contribution of each group member

    • On your README, please provide a brief documentation to show that each group member has contributed fair share of work for Assignment 1, Part 2.
  6. Push to GitHub and Deploy to Heroku

    • Create your own GitHub repository and Heroku application
    • After deploying your application to Heroku, following commands may be needed for OAuth to work successfully. Here's an example for Twitter OAuth:
    heroku addons:add mongolab
    heroku config:set TWITTER_CONSUMER_KEY=<your consumer key without quotes>
    heroku config:set TWITTER_CONSUMER_SECRET=<your consumer secret without quotes>
    heroku config:set SESSION_SECRET=4fa238c5d0d632881b6786f3b2d944950169948f
    

Rubric

This assignment is out of 20 points and will be graded on Part 2. It will be graded heavily on how you apply design skills taught in COGS 121 using given technologies. Certain points may be awarded for excellent execution of the project (e.g. 2nd criteria will be awarded for application(s) that are truly creative/innovative and improves the communication).

For usability heuristics criteria, following the heuristics is worth 1 point each per heuristic. To receive the full point for a heuristic, you must apply that heuristic somewhere in your application. No use of a heuristic results in 0 points for that heuristic. If you apply a heuristic somewhere in your application, but violate that same heuristic somewhere else in your application, you will only receive 0.5 points for that heuristic. (Note: for some of the heuristics like recognition over recall, applying is the same as not violating, so just worry about not violating that heuristic). For each heuristic, include a one sentence description in the README of how your application addresses that heuristic.

It is expected that each group member contributes to Part 2 fairly. The distribution of work should determined by group consensus and responsibility should be given that member's expertise (either technical or design). Document the distribution of work in the README file.

It is required that your application utilizes Passport.js, this will help us understand if you understood Part 1 of this assignment.

It is not required but highly recommended that your application utilizes Socket.io. As such, it will count as 1 point extra credit.

And YAY! Free points for turning-in Assignment 0 in time.

Criteria Points
INDIVIDUAL: Turned-in Assignment 0 in time 2
The application follows good usability heuristics with minimal to no violations (README) 10
The application has a clear theme and target audience 1
The application is creative/innovative 2
The application effectively utilizes Passport.js to handle user authentication 2
The application effectively utilizes Socket.io to handle live communication 1 (bonus)
All group members contributed fairly to this project (README) 1
INDIVIDUAL: Peer review completed (CATME) 2
The assignment has been submitted prior to the Noon of April 14, 2016 1 (bonus)

Submission Guidelines:

The code/application that you are submitting is what you create in part 2 only, as that is the only portion that is graded. You will need to understand part 1 to be able to complete part 2, but you do not need to submit part 1. Your team will also need to complete peer evaluation to complete the assignment.

Submission details for CATME will be released during week 3

Please submit your assignment via this Google Form

Clone this wiki locally