Introduction
For the team project, you will build a web app where many users interact with each other in real-time,
and deploy it on the Internet. You have a large amount of freedom in what you build as long as it
meets the criteria outlined in this document.
In the homework, you built every feature starting from a TCP socket. In the project, you'll build an app of
your own design with a web framework. The project is meant to give you experience with real-world web app
development and you are allowed to use any resources you would be able to use on the job, including LLMs.
The project is divided into 4 objectives, worth 20 points each, and a presentation also worth 20 points.
Individual grading adjustments may apply to each team member based on their individual effort and completion
of the report and peer eval form.
Submissions
The project has the following submissions. Please remember to complete all submissions for your project to be
properly graded:
Project submissions
| Submission |
Submitted by |
What it includes |
|
Team
Formation Form
|
One member of each team |
The members of your team |
|
Team
Details
Form
|
One member of each team |
The link to your team's GitHub repository (It must be public), and a short description of your app
plan
|
|
Presentation Sign Up
|
One member of each team |
Your team's presentation time |
|
Report
and Peer Evals
|
Every team member |
What you did for the project, and your evaluation of each of your teammates |
Report, Peer Evals, and Individual Grading
By the project deadline, every team member must submit the
report
and peer eval form. In your report, you must:
-
List each feature or part of the project you worked on, and explain what you did
-
Link to your commits on GitHub for each item in your list. These must be commits that you authored on
the default branch of your team's repo
-
Evaluate each of your teammates
Reports are individual assignments: Write your own, and describe only your own work.
The points described in this document determine your team score for the project. Your actual grade may be
adjusted based on your individual contributions to the project. These decisions will be made on a
case-by-case basis at the discretion of the course staff. Factors used to determine these adjustments
include:
- Your report
-
Not submitting a report is an easy way to earn a negative individual grade adjustment, probably
all the way to 0/80 on the project objectives (You could still earn 20 points from the presentation)
-
The quality of your report will be taken into account as well (eg. "I worked on the backend"
with a link to a single commit is a low quality report)
- Your teammates' evaluations of you
-
If your teammates rated you poorly/excellently, your grade may be adjusted down/up respectively.
This is not automatic. All cases will be reviewed by the course staff to verify each situation
- Your commits in the team repo
-
Your commits may be checked to see if you did in fact complete the work you described in your
report, as well as compare the amount of work you completed to that of your teammates
-
You MUST commit your own code! It is not acceptable for your teammate to commit your code for
you. You should have a clear separation between your tasks and commit the code for your task.
If a commit is not in your name, you effectively did not write that code. If a teammate is
making this difficult, let the course staff know in your peer evals
-
If you don't have any commits on the default branch of the repo, you effectively did not work on
the project and will earn a 0 after individual grade adjustments
How Your Project is Tested
Objectives 1-4 [except the deployment requirements of Objective 1] will be tested by:
-
Cloning your repo
-
Running "docker compose up"
-
Navigating to http://localhost:8080/ in a browser and testing all the features of your app
The deployment requirements of Objective 1 are tested using the link to your deployed app in your readme.
For grading purposes, we will check out your latest commit that was made before the deadline.
It is strongly recommended that you test your app by cloning a fresh copy of your repo, after the last
commit for the deadline, and going through these steps. This will simulate exactly what we'll do during
grading and will expose any setup issues you may have. It is common for an app to run in your working
directory, but not from a fresh clone (eg. If you have dependencies installed locally in a .venv or
node_modules directory, or a file/directory that was never committed). Test your app to make sure it will run
during grading.
Objective 1 - Deployment
This objective is the foundation of your app. You have the freedom to choose any language, database,
framework, etc for this project, and this objective is where you'll make those choices. Your app must
contain the
following features and structure:
-
Framework
-
You are required to use a web framework (You cannot start from a TCP
socket. That's what the homework was all about). You have full freedom in choose your framework,
including which language to use for this project
-
If you're not sure if something counts as a
web framework,
feel free to ask the course staff
-
Docker Compose
-
Set up your project using Docker and docker compose. Your app must run on local port 8080 after
running "docker compose up". You may choose to map additional ports, but 8080 must also be available
over HTTP if you do
-
Run nginx as a reverse proxy. This may be in a separate container using docker compose, installing
nginx
directly
on your production server, or both
-
Database
-
You may use whatever database you'd like (ie. You do not have to use Postgres), though your
database must run in a separate container that is started using docker compose (ie. A local SQLite
instance is not allowed)
-
Home Page
-
Your framework serves a home page at "/". For this objective, a static
page is enough
-
Deployment
-
Deploy your app on a publicly available server with a domain name and HTTPS with a valid
certificate. It is recommended that you
take advantage of the
GitHub Student Developer
Pack which includes offers for free domain names for 1 year. Add a DNS record for your
domain name that points to your instance
-
Your certificate must be valid. It's recommended that you use Certbot to acquire a free
certificate from Let's Encrypt
-
Requests to http:// (port 80) must redirect to the same path on https:// (port 443)
-
Add a link to your deployed app in the readme of your repository so we can find your deployment
-
Your app must still run locally at http://localhost:8080 with "docker compose up" since that's
how we'll test the rest of the project. You may want to create a separate branch, or a separate
compose file, for the deployed version of your app, or ensure that all feature work both with
and without TLS
Security Concern - Ensure that your database is not accessible to the world.
For example, if you're using MongoDB and you map your port (eg. 27017:27017) in compose.yml, anyone
with an internet connection can access your database. You may want to map this port for
testing purposes in your
development environment, but this MUST be removed before deploying.
Security Concern - Do not commit your certificate's private key to your repo.
Security Concern - Any security concern covered in any homework also applies. This includes
HTML injection, SQL injection, XSRF protection, proper cookie directives, etc. This applies to all 4 objectives.
Specific security details cannot be provided due to the open-ended nature of the project
Objective 2 - Authentication with JWT's and an Auth Server
Add accounts to your app, with a twist: A separate authentication (auth) server issues JWTs, and your app
verifies them without asking the auth server or the database who the user is.
-
Registration and Login
-
There should be a clear way for users to register, login, and logout. Once logged in, there
should be a clear visual letting the user know that they are logged in (eg. Display their
username on the home page)
-
Authenticated sessions must be persistent - If a user logs in then you restart all your
containers, they should be able to refresh the page and still be logged in
-
The Auth Server
-
Create a separate auth server that runs in its own container. It handles all registration,
login, and logout requests, and issues a JWT when a user logs in
-
Use nginx to route all authentication requests (/register, /login, /logout) to your auth
server, and all other requests to your app. You may route more paths to your auth server if
you'd like, but only these 3 are required
-
Auth-related requests must never be seen by your app container
-
JWTs
-
JWTs must be cryptographically signed using a private key that only your auth server can
access (eg. RS256). Your app verifies them with the matching public key
-
Your app must verify JWTs without communicating with the auth server and without a database
lookup. After the JWT is verified, you may still use the database (eg. To pull information
about the user). You just can't use it to
verify the user's identity
-
You will have to solve the problem of generating a public/private key pair, keeping the private
key only on the auth server, and sharing the public key with your app. Your keys must survive a
restart (Otherwise every JWT becomes invalid and your sessions are not persistent). You may
give your app the public key through a shared volume, or by adding an endpoint to your auth
server that returns the public key. That endpoint is the only direct communication allowed
between the two
-
Each JWT must expire. Include the "exp" claim and reject expired tokens in your app
Security Concern - Your JWTs must be signed in a way that they cannot be forged. Your app must
reject tokens with an
invalid signature, tokens signed with a different algorithm than the one you chose, and expired tokens.
Objective 3 - WebSockets
This is the core of your app and the part your audience will use during your presentation. Build a feature
where many users [within reason] are in the same shared space at the same time and see each other's actions
as they happen. You have much freedom in what you build as long as WebSockets are actually needed to build
it (eg. The lag of polling, even at a polling interval of ~500ms, would create a terrible user experience).
To check if your idea needs WebSockets, imagine every update arrived half a second late, as it might if each
browser polled your server for changes. If your app would still work fine, it doesn't need WebSockets. A chat
app, a turn-based game, an auction site, or a feed of new posts all work fine with a half-second delay, so none of these
satisfy this objective. Players moving around a game world would feel broken with that delay.
We recommend building a real-time massively multiplayer online (MMO) game since it naturally meets every
requirement for this objective. If you're lacking ideas, agar.io is an example of a game that
meets all these criteria, without being overly complex. If you have an idea that isn't a game, you can still build it as long as it meets
all the requirements. If you're not sure if your idea qualifies, feel free to ask the
course staff.
-
Shared Space
-
There must be a visual representation of the shared space. You may choose how users join, or if
every logged-in user automatically joins when they load the home page. When a user is in the
shared space, they should be able to see all other users in it and what they're doing
-
Real-Time Updates
-
The actions of each user must be broadcast to all other users in real time using WebSockets.
This means all users see each other's actions as they happen [minus network delays]
-
All users must be able to act at the same time (eg. Turn-based games are not allowed)
-
Your idea must need WebSockets, as described above. If your app would work just as well with a
half-second delay (between a user taking an action and all other users seeing that action),
this objective is not complete
-
There must be some form of interaction between users. This does not have to be substantial, but there
must be something more than users moving around in a shared space. These interaction must benefit from
WebSockets with the same "500ms delay would feel bad" criteria
-
Your deployed app uses WSS through nginx. Be sure your WebSocket connection still works when ran
locally using HTTP
-
Authenticated Connections
-
Only logged-in users can join. Your app verifies the JWT from the WebSocket handshake request
before accepting the connection, and uses the username from the verified JWT for everything that
user does. A user must never be able to act as another user
You have many options for the visuals of your app. You will not be graded on how visually appealing your app
is so an HTML canvas with basic shapes will suffice. If you're building a game and want to make something
more impressive though, you should consider using a game framework like
phaser.io.
Objective 4 - Make it Interesting
A web app is just an app that users interact with through web protocols. In this course, you learned how to
turn HTTP requests and WebSocket messages into app functionality. Once you can do that, anything you know
how to program can become part of a web app.
For this objective, add a feature to your app that is built on something you learned outside of this course.
This can be something from another course you've taken, or something new that you learn on your own for this
project. Choose from one of the categories below. If you have an idea that does not fit any of the categories,
you may propose it for approval and the course staff will decide if it meets the spirit of this objective.
If you are not sure if you idea qualifies, feel free to ask the course staff if it does.
Requirements:
-
Beyond This Course
-
The topic must not be covered in this course. Using a different web framework or database, or
anything from our lectures (eg. WebRTC, encryption, OAuth), does not count
-
Part of Your App
-
This feature must connect to your Objective 3 feature. It is recommended that you plan you idea for
objectives 3 and 4 simultaneously instead of planning objective 4 after objective 3 is built
-
Write-Up
-
Add an "Objective 4" section to the readme of your repository that explains what you
built for this objective
-
Presentation
-
Demo this feature during your presentation and explain what you built. If your feature can't
be run with "docker compose up" (eg. It uses specialized hardware), your presentation is how
we'll see it working
Categories
Below are the categories you may choose from for this objective. Each category lists several examples/ideas
that can choose, or come up with an idea of similar rigor in your favorite category.
-
AI and Machine Learning
-
Train a model or implement an AI algorithm that powers a feature of your app. Examples: Bots
that play against your users using search (eg. Minimax or Monte Carlo tree search) or
reinforcement learning; A model trained on data your app collects (eg. Detecting bots or cheaters
from how they move); Recommendations based on what users do in your app
-
Sending a prompt to a hosted model (eg. An LLM API) and integrating the response into your app
-
Databases and Data
-
Do more with your data than store, look up, and joins. Examples: Replays, where your app records
every event and users can watch any past session play back, spatial queries that find nearby
users fast enough to run on every update, or a database
replicated across several containers that keeps working when the primary is stopped
-
Systems and Networking
-
Change how your app runs, scales, or communicates. Examples: Horizontal scaling, where several
copies of your app run behind nginx and users connected to different copies still see each other
in real time, netcode techniques from game development (eg. Client-side prediction, server
reconciliation, and interpolation) that keep movement smooth when latency is high, a compact
binary format for your WebSocket messages, fault tolerance, where an app container can crash
without users noticing
-
Theory and Algorithms
-
Implement a nontrivial algorithm at the core of a feature. Examples: Procedural generation of your
world (eg. Noise functions or wave function collapse), collision detection that scales to many
users (eg. Something more efficient than O(n^2) collision detection), skill ratings and
matchmaking (eg. Elo)
-
Hardware
-
Connect a physical device to your app using HTTP or WebSockets just like a
browser. Examples: A microcontroller (eg. ESP32 or Raspberry Pi Pico W) used as a controller for
your game, sensors that stream live data into your app, lights, motors, or a display that reacts
to what users do in your app
-
Build a desktop or mobile app for your game. All users of your app, whether desktop, mobile, or web,
must be able to interact with each other
-
Graphics and Interaction
-
Go beyond drawing shapes on a canvas. Examples: Using OpenGL or phaser.io to make a visually appealing app,
spatial
audio that lets users hear where other users are
Presentation
Sign up for a presentation time: https://calendly.com/hartloff/cse312-presentations
You will give a presentation demoing your project and opening it for the audience to test. You must
demo from the deployed version of your app, and the audience will use your app during your demo.
Your presentation should be 8-10 minutes. All team members must be present, at the front of the room, and
speak during the presentation. Each team member should speak for a roughly equal share of the time, so plan
ahead for who will present each part (eg. Each member can demo the features they built). Any team members who
are not present, or who do not speak, will earn 0 points for the presentation (This does not affect the
grade of the rest of the team).
Your app must be deployed and publicly available during your presentation. You must share the link and the
app must be functional for anyone in the audience.
Your deployed app must be accessible via HTTPS with a valid certificate. There must not be any security
warnings (ie. self-signed certificates) when a user visits your app.
If your app is not properly deployed, your team will earn 0 points for the presentation.
Demo (10 points)
Demo the functionality of your app from the user perspective. Run your app and show all the
functionality of the required features as well as any additional features
your team implemented. For any features that are incomplete, you should still mention the feature and the
status of development. You can still earn full credit for the presentation even if some features are not
complete or functional.
Your demo must include your Objective 4 feature. Explain what you learned, how it works in your app, and
show your evidence that it works.
During the demo portion of your presentation, it is recommended that you hide your URL from the audience.
Leaking the URL early can entice someone in the audience to use your app during the demo. You should finish
your demo before revealing your URL and moving to the user tests.
User Tests (10 points)
After your demo, reveal your URL to the audience so everyone in attendance can test your app. During this
test, everyone should be able to use your app without issue. Your app should be able to handle the load of
all the users in the audience at the same time without crashing or suffering severe performance issues.
Grading
Unlike the homework objectives, partial credit may be given for each project objective.
Objectives 1-4 list their requirements. Each of these objectives earns all its points when every requirement
is functional. Points are deducted for each requirement that is missing or not working. This includes issues
running Docker or docker compose even if the code for the objective is correct.
If a security risk is found while testing an objective, all objectives earn 0 points. You can recover your
points by submitting a security essay. These essays must be submitted on an individual basis, even for team members
who had no part in the feature with the security issue.
An objective earns 0 points if it violates the assignment (Ex. Not using a web framework).
A Security Risk is any violation of a "Security Concern" that is explicitly labeled in this document.
Security Essay
If a security risk is found in your submission, you will be assigned a 0 for all 4 objectives.
However, you will still have an opportunity to earn credit for the objectives by submitting an essay about
the security issue you exposed. These essays must:
- Be at least 1000 words in length
- Explain the security issue from your submission with specific details about your code
- Describe how you fixed the issue in your submission with specific details about the code you changed
- Explain why this security issue is a concern and the damage that could be done if you exposed this issue
in production code with live users
If your project contains multiple security risks, you may have to write multiple essays to recover your
project grade
Any submission that does not meet all these criteria will be rejected and your project grade will remain 0/80.
Due Date: Security essays are due 1-week after grades are released. Submission instructions will be included in
your feedback on Autolab.
Any essay may be subject to an interview with the course staff to verify that you understand the importance
of
the security issue that you exposed. If an interview is required, you will be contacted by the course staff
for
scheduling. Decisions of whether or not an interview is required will be made at the discretion of the
course
staff.