diff --git a/README.md b/README.md index 571e84a..26dec2c 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,142 @@ -# textroulette -CS96 Dev Team first project -- a text-based communication tool, driven by Node.js +# Eye to Eye -*This repo autodeploys to https://cs96.tk* +Eye to Eye is a nonpartisan web application that enables you to have face-to-face conversations with strangers who have different views from your own. + +# Table of Contents + +1. [Getting Started](#getting-started) +2. [Technical Documentation](#technical-documentation) + * [Technical Overview](#technical-overview) + * [Configuration](#configuration) + * [Database](#database) + * [Routes](#routes) + * [Views](#views) + * [Controllers](#controllers) + * [Matcher](#matcher) + * [WebSockets](#websockets) + * [Static Assets](#static-assets) +3. [About](#about) + +# Getting Started Before running, please ensure that you have a `.env` file in the root directory in the format `KEY=VALUE`, one per line. `.env` should contain the following keys: * DB_URI: an complete MongoDB connection URI -* FB_ID: `1820618154618978` (only usable for localhost:3000) or your own FB app ID +* FB_ID: a valid Facebook Developer App ID +* FB_SECRET: a valid Facebook Developer App Secret +* FB_CALLBACK: by default, `http://localhost:3000/auth/facebook/callback`; you should change the host and port of `FB_CALLBACK` to reflect actual the configuration in production. + +Then, run `npm install`. Finally, run `npm start`. + +To run on a port other than `3000`, change the `PORT` and `FB_CALLBACK`environment variables as well as the configuration in Facebook Developer. + +# Technical Documentation + +## Technical Overview + +Eye to Eye is powered by a *node.js + express* backend. Pages are rendered server-side using the *Handlebars* templating engine. *Socket.io*, a wrapper around the *WebSocket* protocol, is used for bidirectional communication between server and client. The client side uses *Bootstrap* and *jQuery* for styling and interactivity and, following a handshake using *Socket.io*, clients initiate video chat using *WebRTC*, facilitated by *SimpleWebRTC* and *Xirsys* STUN servers. *tracking.js* is additionally used during video chat for facial masking. Data is stored using *MongoDB*. + +Eye to Eye's main exectuable is `/server.js`, which: +* loads configurations from `/config` and `/.env` +* connects to MongoDB with *mongoose* and models in `/db` +* configures an *express* app using routing logic in `/routes` powered by logic in `/controllers` and rendering views in `/views` +* instantiates the matcher engine in `/matcher.js` +* initializes WebSocket communication from `/sockets.js` +* serves static resources from `/static` + +Finally, in auto-deployment, shell scripts in `/scripts` are used to start/restart/stop the server using *nginx* and *pm2*. + +## Configuration + +The npm packages *dotenv* and *getconfig* are used for configuration. *getconfig* uses JSON to store configuration in `/config/default.json` and *dotenv* uses key-value pairs stored in `/.env`. + +Data stored in `/config/default.json` is inevitably passed to the client side and is thus not secret, meaning that it can be safely committed. Data stored in `/.env` is not committed (and blacklisted by `/.gitignore`) because it contains sensitive API keys. + +To load this configuration, the following code is run in `/server.js`: + +``` +require('dotenv').config(); +var config = require('getconfig'); +``` + +This stores the environment variables in `/.env` in `process.env` and the JSON in `/config/default.json` into the variable `config`. + +## Database + +The server connects to MongoDB by requiring `/db/connect.js`, which initializes a connection to the instance the `DB_URI` from `/.env`. `/db/connect.js` also exports models from `/db/models/`. + +## Routes + +Most routes are contained in `/routes/main.js`. Routes often use the `isLoggedIn` function to ensure that users are authenticated and redirecting them to `/` otherwise. Authentication is powered by *passport.js* and relevant data is stored in `req.user` after successful authentication. + +Routes that render *Handlebars* views in `/views` pass the data returned by the `getAuthInfo` function to the frontend, which allows the frontend to access user account data. API routes are powered by controllers in `/controllers`. + +### List of Routes + +| Route | Requires Authentication | Type | Description | +|-----------------------------|-------------------------|----------|--------------------------------------| +| `GET /` (unauthenticated) | No | View | Landing page | +| `GET /` (authenticated) | Yes | View | User profile | +| `GET /chat` | Yes | API | Video chat | +| `GET /about` | Yes | View | About | +| `GET /text` | Yes | View | Text chat (legacy) | +| `GET /profile` | Yes | Redirect | / | +| `GET /profile/user` | Yes | API | Return req.user as JSON | +| `GET /profile/leaderboard` | Yes | API | Returns user's leaderboard | +| `GET /profile/chats` | Yes | API | Returns user's past chats | +| `GET /questions` | No | API | Returns active questions | +| `GET /updateStance` | Yes | View | Update opinions | +| `POST /updateStance` | Yes | API | Set user's opinions | +| `GET /feedback` | No | View | Submit conversation feedback | +| `POST /feedback` | Yes | API | Submit conversation feedback | +| `POST /feedback/report` | Yes | API | Submit report against user | +| `GET /login` | No | Redirect | /auth/facebook | +| `GET /auth/facebook` | No | Redirect | Facebook (for authentication) | +| `GET /auth/facebook/callback` | No | Redirect | / if success, /auth/error if failure | +| `GET /auth/error` | No | Text | "Auth failure :(" | +| `GET /logout` | No | Redirect | / after loging out | +| `GET /terms-of-use` | No | View | TOS | + +Note in particular that there is no route for modifying active questions. In the current implementation, questions are manually modified in the database. + +## Views + +Views are contained in `/views` and are powered by Handlebars. Similar to PHP, Handlebars is a superset of HTML syntax that allows accessing JSON-formatted variables with `{{{variable}}}`. All views begin with the `/views/layouts/main.handlebars` layout and may utilize the partial views in `/views/partials`. HTML elements in views generally are styled using *Bootstrap* classes, while *jQuery* is used for interactivity. The view */views/video.handlebars* extensively utilizes *Socket.io* and *SimpleWebRTC* to communicate with the server for pairing and disconnection. + +During video chat, *SimpleWebRTC* uses an existing *