Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
581cb49
Our project proposal
gabestuf Sep 28, 2022
f5f86b6
nodemon
jdpalmieri Sep 28, 2022
ecbb930
Merge branch 'main' of https://github.com/gabestuf/final_project
jdpalmieri Sep 28, 2022
3eeda09
started working on model for REST api
gabestuf Sep 30, 2022
353b710
init backend
gabestuf Oct 3, 2022
1604320
user routes
gabestuf Oct 6, 2022
65bb65d
Home Page, Login, Sign up
AidanMulcahey Oct 6, 2022
13492fd
Login, Create, Home Page
AidanMulcahey Oct 6, 2022
e2ada2c
refactor server.js
gabestuf Oct 6, 2022
c7c8ffb
experimenting with jwt for auth
gabestuf Oct 7, 2022
ffeb524
connected signup to DB, removed firstname & lastname fields, not needed
gabestuf Oct 7, 2022
832c998
sleep
gabestuf Oct 7, 2022
a475818
changed /createaccount to /signup
gabestuf Oct 7, 2022
96156b8
updated api json
gabestuf Oct 7, 2022
cc3fb82
login page done
gabestuf Oct 9, 2022
912f44b
leaderboard api and mongo integration
gabestuf Oct 10, 2022
a5abe21
Leaderboard, home buttons
AidanMulcahey Oct 11, 2022
c965c68
s
gabestuf Oct 11, 2022
ccaa590
Merge branch 'main' of https://github.com/gabestuf/final_project
gabestuf Oct 11, 2022
67ccb45
spell fixes
AidanMulcahey Oct 11, 2022
97bd349
s
gabestuf Oct 11, 2022
ce6aa45
help me
gabestuf Oct 12, 2022
888ed61
game
gabestuf Oct 12, 2022
473917a
design for leaderboard, bug fixes
AidanMulcahey Oct 13, 2022
eb4d8c6
edit style a little
gabestuf Oct 13, 2022
c062340
final
gabestuf Oct 13, 2022
ee2b63f
Fasdsdsdasd
gabestuf Oct 13, 2022
8d2a630
small optimizations and user experience improvements
gabestuf Oct 13, 2022
969eccf
edited README
gabestuf Oct 13, 2022
1d3b4fd
Update README.md
gabestuf Nov 18, 2022
e7854ee
Update README.md
gabestuf Jan 12, 2023
9b4ce4f
deploy w/ vercel
gabestuf Jan 12, 2023
958f6e9
Merge branch 'main' of https://github.com/gabestuf/final_project
gabestuf Jan 12, 2023
8e9ab81
server.js to index.js
gabestuf Jan 12, 2023
3bb3e84
updated vercel.json
gabestuf Jan 12, 2023
615d7d6
updated vercel.json
gabestuf Jan 12, 2023
5f7d48e
v
gabestuf Jan 12, 2023
54174e9
V
gabestuf Jan 12, 2023
fba445f
deleted a comment
gabestuf Jan 12, 2023
03c209e
edited vercel.json
gabestuf Jan 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.env
.vercel
23 changes: 23 additions & 0 deletions Proposal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Associates
Gabriel Camacho
Aidan Mulcahey
Jonathan Palmieri





**Specifications**
We are going to create a game featuring a log in system and a leaderboard.
The highest game score per user will be stored on the user account and on a global leaderboard.
The game itself will be completely clientside, with the scores being sent to a mongDB instance at the end of the game.
We are going to create a 2D platforming game where the objective is for your player sprite to get from point A to point B
There will be collision obstacles. You get timed and score is based on time.

Key technologies:
MongoDB - Store user info & leaderboard
Express - For backend
Authentication for login - An authentication library or with cookies
Mongoose for mongoDB - easier interaction with database
NodeJS - for obvious reasons
Game engine (in JS) to create game - experimenting with game engines and game design
57 changes: 11 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,14 @@
# Final Project
*Due before the start of class, October 13th (final day of the term)*
## Aim Trainer / Reaction Time Game, Heroku:

For your final project, you'll implement a web application that exhibits understanding of the course materials.
This project should provide an opportunity to both be creative and to pursue individual research and learning goals.
(No longer working) https://aimtrainer-webware.herokuapp.com/

## General description
Your project should consist of a complete Web application, exhibiting facets of the three main sections of the course material:
## Aidan Mulcahey, Gabriel Camacho, Jonathan Palmieri

- Static web page content and design. You should have a project that is accessible, easily navigable, and features significant content.
- Dynamic behavior implemented with JavaScript (TypeScript is also allowed if your group wants to explore it).
- Server-side programming *using Node.js*. Typically this will take the form of some sort of persistent data (database), authentication, and possibly server-side computation.
- A video (less than five minutes) where each group member explains some aspect of the project. An easy way to produce this video is for you all the groups members to join a Zoom call that is recorded; each member can share their screen when they discuss the project or one member can "drive" the interface while other members narrate (this second option will probably work better.) The video should be posted on YouTube or some other accessible video hosting service. Make sure your video is less than five minutes, but long enough to successfully explain your project and show it in action. There is no minimum video length.

## Project ideation
Excellent projects typically serve someone/some group; for this assignment you need to define your users and stakeholders. I encourage you to identify projects that will have impact, either artistically, politically, or in terms of productivity.

### Deliverables

#### Form Team (due 9/25)
Students are will work in teams of 3-5 students for the project; teams of two can be approved with the permission of the instructor. Working in teams should help enable you to build a good project in a limited amount of time. Use the `#project-logistics` channel in Discord to pitch ideas for final projects and/or find fellow team members as needed.

Teams must be in place by end of day on Sunday, September 25th. If you have not identified a team at this point, you will be assigned a team. You will be given some class time on Monday to work on your proposal, but please plan on reserving additional time outside of class as needed.

#### Proposal (due 9/27)
Provide an outline of your project direction and the names of associated team members.
The outline should have enough detail so that staff can determine if it meets the minimum expectations, or if it goes too far to be reasonable by the deadline. Please include a general description of a project, and list of key technologies/libraries you plan on using (e.g. React, Three.js, Svelte, TypeScript etc.). Two to four paragraps should provide enough level of detail. Name the file proposal.md and submit a pull request by Tuesday, September 27th at 11:59 PM (end of day). Only one pull request is required per team.

There are no other scheduled checkpoints for your project.

#### Turning in Your Project
Submit a second PR on the final project repo to turn in your app and code. Again, only one pull request per team.

Deploy your app, in the form of a webpage, to Glitch/Heroku/Digital Ocean or some other service; it is critical that the application functions correctly wherever you post it.

The README for your second pull request doesn’t need to be a formal report, but it should contain:

1. A brief description of what you created, and a link to the project itself (two paragraphs of text)
2. Any additional instructions that might be needed to fully use your project (login information etc.)
3. An outline of the technologies you used and how you used them.
4. What challenges you faced in completing the project.
5. What each group member was responsible for designing / developing.
6. A link to your project video.

Think of 1,3, and 4 in particular in a similar vein to the design / tech achievements for A1—A4… make a case for why what you did was challenging and why your implementation deserves a grade of 100%.

## FAQs

- **Can I use XYZ framework?** You can use any web-based frameworks or tools available, but for your server programming you need to use Node.js. Your client-side scripting language should be either JavaScript or TypeScript.
1. Aim Trainer Game with a Login Page, Create an Account Page, Leaderboard Page and Game page. The goal of the game
is to click the green buttons that appear on the screen as fast as you can. Each user's high score will automatically
be entered on the leaderboard. Users will be notified when they beat their own high score.
2. Instructions: Create an account and/or proceed to log in. This will take you to the game page, where you can attempt to get a good score on the Aim Trainer. Initiate the game by pressing the Start Game button. At any point, check the leaderboard to see how you are doing versus the other users.
3. Express, MongoDB, argon2, dotenv, ejs, jsonwebtoken, mongoose
4. Challenges included using timeout and time based events in the game including starting and stopping the game. Another challenge included getting the targets to appear randomly in the container, which is 95% functional, but targets clip once in a while. User authentication was much easier this time after practice in hw3 & 4
5. Aidan Mulcahey - Login, Create an Account, Leaderboard Page, & Design, Gabriel Camacho - created game and set up routes for backend, Jonathan Palmieri - wrote server code to connect and communicate with database
6. Link to Video: https://www.youtube.com/watch?v=QydoE20bjdE
146 changes: 146 additions & 0 deletions api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@


const api = {
'GET': [
{
'/': 'home.html',
desc: 'serves home page to user, this page will have login/signup buttons'
},
{
'/home': 'home.html',
desc: 'serves home page to user, this page will have login/signup buttons'
},
{
'/signup': 'signup.html',
desc: 'serves signup page'
},
{
'/login': 'signin.html',
desc: 'serves signin page'
},
{
'/leaderboard': 'leaderboard.html',
desc: 'serves leaderboard page'
},
{
'/profile/:user': 'profile.html',
desc: 'shows user profile, username, high score, option to change password'
},
{
'/game': 'game.html',
desc: 'serves game page'
},
{
'/leaderboard/getLeaderboard': {
res: {
body: ["array of {username: String, score: Number}"]
}
},
desc: 'gets leaderboard info from mongoDB'
}

],
'POST': [
{
'/user/signin': {
req: {
body: {
username: String,
password: String
}
},
res: {
status: "SUCCESS / FAILED",
message: String,
username: String, // on success
data: String, // on success
accessToken: String // on success
}
},
desc: 'used for logging in, authenticates user and creates an auth token'
},
{
'/user/signup': {
req: {
body: {
username: String,
password: String,
userdata: String
}
},
res: {
body: {
status: "SUCCESS / FAILED",
message: String,
data: String // on success
}
},
},
desc: 'used for logging in, authenticates user and creates an auth token'
},
{
'/auth/login': {
req: {
body: {
username: String
}
},
res: {
body: {
accessToken: String,
refreshToken: String
}
}
}
},
{
'/auth/token': {
req: {
body: {
token: String
}
},
res: {
body: {
accessToken: String
}
}
}
},
{
'/leaderboard/submitScore': {
req: {
body: {
username: String,
accessToken: String,
score: Number
}
}
}
}
],
'DELETE': [
{
'/auth/logout': {
req: {
body: {
token: String
}
},
res: {
status: "SUCCESS/FAILED"
}
}
}
]
}

//MONGODB Models
const User = {
username: String,
password: String,
highscore: Number
}
const Leaderboard = {
leaderboard: String, // where String is array [{username: String, score: Int}, {username: String, score: Int}]
}
56 changes: 56 additions & 0 deletions api/Auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const express = require('express')
const authRouter = express.Router()
// INIT
require('dotenv').config()
authRouter.use(express.json())
// authorization
const jwt = require('jsonwebtoken')
const auth = require('../middleware/Authorization')


// Ideally stored in a database
let refreshTokens = []

authRouter.get('/game/:authToken', auth, (req, res, next) => {
if (req.user) {
res.redirect('/game')
next()
} else {
res.redirect('/login')
}
})

authRouter.post('/login', (req, res) => {
const username = req.body.username
const user = { name: username }

const accessToken = generateAccessToken(user)
const refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SECRET)
refreshTokens.push(refreshToken)
res.json({ accessToken: accessToken, refreshToken: refreshToken })
})

authRouter.post('/token', (req, res) => {
const refreshToken = req.body.token
if (refreshToken == null) { return res.status.sendStatus(401) }
if (!refreshTokens.includes(refreshToken)) {
return res.sendStatus(403)
}
jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET, (err, user) => {
if (err) {
return res.sendStatus(403)
}
const accessToken = generateAccessToken({ name: user.name })
res.json({ accessToken: accessToken })
})
})
authRouter.delete('/logout', (req, res) => {
refreshTokens = refreshTokens.filter(token => token !== req.body.token)
res.sendStatus(204)
})

const generateAccessToken = (user) => {
return jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, { expiresIn: '30m' })
}

module.exports = authRouter;
101 changes: 101 additions & 0 deletions api/Leaderboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
const express = require('express')
const leaderboardRouter = express.Router()

require('dotenv').config()
leaderboardRouter.use(express.json())


//mongoDB Leaderboard model
const User = require('./../models/User')

leaderboardRouter.get('/getLeaderboard', (req, res) => {

User.find()
.then(data => {
if (data.length) {
let arr = []
for (const key in data) {
let s = {
'username': data[key].username,
'highscore': data[key].highscore
}

arr.push(s)
}
res.json({
status: "SUCCESS",
message: "got leaderboard list",
data: JSON.stringify(arr)
})
} else {
res.json({
status: "FAILED",
message: "No data found",
data: JSON.stringify([])
})
}

})
.catch(e => {
res.json({
status: "FAILED",
message: e.toString()
})
})
})

leaderboardRouter.post('/submitScore', (req, res) => { //add auth eventually
const { username, score } = req.body

User.findOne({ 'username': username }, (err, foundObject) => {
if (err) {
console.error(err)
res.json({
status: "FAILED",
message: "Error finding user"
})
} else {
if (!foundObject) {
res.json({
status: "FAILED",
message: "User not found"
})
} else {
if (req.body.username) {
let highscore = JSON.parse(foundObject.highscore)
if (score > highscore) {
foundObject.highscore = score;
foundObject.save((err, updatedObject) => {
if (err) {
res.json({
status: "FAILED",
message: "Error=1"
})
} else {
res.json({
status: "SUCCESS",
message: "Edited highscore",
updatedObject: { username: updatedObject.username, highscore: updatedObject.highscore }
})
}
})
} else {
res.json({
status: "FAILED",
message: `Your previous score of ${highscore} was better`
})
}


} else {
res.json({
status: "FAILED",
message: "Error=2"
})
}
}
}
})
})

module.exports = leaderboardRouter
Loading