├── .gitignore ├── README.md ├── app.js ├── controllers ├── gamecontroller.js └── usercontroller.js ├── db.js ├── middleware └── validate-session.js ├── models ├── game.js └── user.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Eleven Fifty Blue Badge Node Debug Challenge 2 | 3 | 1. Clone Repo 4 | 2. Run ```npm install``` 5 | 3. Change postgres password in ```db.js``` 6 | 4. Create ```'gamedb'``` in pgAdmin 4 7 | 5. Run ```'nodemon app.js'``` 8 | 6. Debug! 9 | 10 | There are ten errors to find. Five compile issues, five logic issues. 11 | 12 | Happy hacking! -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | var db = require('./db'); 4 | var user = require('./controllers/usercontroller'); 5 | var game = require('./controllers/gamecontroller') 6 | 7 | 8 | db.sync(); 9 | app.use(require('body-parser')); 10 | app.use('/api/auth', user); 11 | app.use(require('./middleware/validate-session')) 12 | app.use('/api/game', game); 13 | app.listen(function() { 14 | console.log("App is listening on 4000"); 15 | }) -------------------------------------------------------------------------------- /controllers/gamecontroller.js: -------------------------------------------------------------------------------- 1 | var router = require('express').Router(); 2 | var Game = require('../db').import('../models/game'); 3 | 4 | router.get('/all', (req, res) => { 5 | Game.findAll({ where: { owner_id: req.user.id } }) 6 | .then( 7 | function findSuccess(data) { 8 | res.status(200).json({ 9 | games: games, 10 | message: "Data fetched." 11 | }) 12 | }, 13 | 14 | function findFail() { 15 | res.status(500).json({ 16 | message: "Data not found" 17 | }) 18 | } 19 | ) 20 | }) 21 | 22 | router.get('/:id', (req, res) => { 23 | Game.findOne({ where: { id: req.params.id, owner_id: req.user.id } }) 24 | .then( 25 | function findSuccess(game) { 26 | res.status(200).json({ 27 | game: game 28 | }) 29 | }, 30 | 31 | function findFail(err) { 32 | res.status(500).json({ 33 | message: "Data not found." 34 | }) 35 | } 36 | ) 37 | }) 38 | 39 | router.post('/create', (req, res) => { 40 | Game.create({ 41 | title: req.body.game.title, 42 | owner_id: req.body.user.id, 43 | studio: req.body.game.studio, 44 | esrb_rating: req.body.game.esrb_rating, 45 | user_rating: req.body.game.user_rating, 46 | have_played: req.body.game.have_played 47 | }) 48 | .then( 49 | function createSuccess(game) { 50 | res.status(200).json({ 51 | game: game, 52 | message: "Game created." 53 | }) 54 | }, 55 | 56 | function createFail(err) { 57 | res.status(500).send(err.message) 58 | } 59 | ) 60 | }) 61 | 62 | router.put('/update/:id', (req, res) => { 63 | Game.update({ 64 | title: req.body.game.title, 65 | studio: req.body.game.studio, 66 | esrb_rating: req.body.game.esrb_rating, 67 | user_rating: req.body.game.user_rating, 68 | have_played: req.body.game.have_played 69 | }, 70 | { 71 | where: { 72 | id: req.params.id, 73 | owner_id: req.user 74 | } 75 | }) 76 | .then( 77 | function updateSuccess(game) { 78 | res.status(200).json({ 79 | game: game, 80 | message: "Successfully updated." 81 | }) 82 | }, 83 | 84 | function updateFail(err) { 85 | res.status(500).json({ 86 | message: err.message 87 | }) 88 | } 89 | 90 | ) 91 | }) 92 | 93 | router.delete('/remove/:id', (req, res) => { 94 | Game.destroy({ 95 | where: { 96 | id: req.params.id, 97 | owner_id: req.user.id 98 | } 99 | }) 100 | .then( 101 | function deleteSuccess(game) { 102 | res.status(200).json({ 103 | game: game, 104 | message: "Successfully deleted" 105 | }) 106 | }, 107 | 108 | function deleteFail(err) { 109 | res.status(500).json({ 110 | error: err.message 111 | }) 112 | } 113 | ) 114 | }) 115 | 116 | module.exports = routers; -------------------------------------------------------------------------------- /controllers/usercontroller.js: -------------------------------------------------------------------------------- 1 | var router = Router(); 2 | var bcrypt = require('bcrypt'); 3 | var jwt = require('jsonwebtoken'); 4 | 5 | var User = require('../db').import('../models/user'); 6 | 7 | router.post('/signup', (req, res) => { 8 | User.create({ 9 | full_name: req.body.user.full_name, 10 | username: req.body.user.username, 11 | passwordhash: bcrypt.hashSync(req.body.user.password, 10), 12 | email: req.body.user.email, 13 | }) 14 | .then( 15 | function signupSuccess(user) { 16 | let token = jwt.sign({ id: user.id }, 'lets_play_sum_games_man', { expiresIn: 60 * 60 * 24 }); 17 | res.status(200).json({ 18 | user: user, 19 | token: token 20 | }) 21 | }, 22 | 23 | function signupFail(err) { 24 | res.status(500).send(err.message) 25 | } 26 | ) 27 | }) 28 | 29 | router.post('/signin', (req, res) => { 30 | User.findOne({ where: { username: req.body.user.username } }).then(user => { 31 | if (user) { 32 | bcrypt.compare(req.body.user.password, user.passwordHash, function (err, matches) { 33 | if (matches) { 34 | var token = jwt.sign({ id: user.id }, 'lets_play_sum_games_man', { expiresIn: 60 * 60 * 24 }); 35 | res.json({ 36 | user: user, 37 | message: "Successfully authenticated.", 38 | sessionToken: token 39 | }); 40 | } else { 41 | res.status(502).send({ error: "Passwords do not match." }) 42 | } 43 | }); 44 | } else { 45 | res.status(403).send({ error: "User not found." }) 46 | } 47 | 48 | }) 49 | }) 50 | 51 | module.exports = router; -------------------------------------------------------------------------------- /db.js: -------------------------------------------------------------------------------- 1 | const Sequelize = require('sequelize'); 2 | 3 | const sequelize = new Sequelize('gamedb', 'postgres', 'ghastb0i', { 4 | host: 'localhost', 5 | dialect: 'postgres' 6 | }) 7 | 8 | sequelize.authenticate().then( 9 | function success() { 10 | console.log("Connected to DB"); 11 | }, 12 | 13 | function fail(err) { 14 | console.log(`Error: ${err}`); 15 | } 16 | ) 17 | -------------------------------------------------------------------------------- /middleware/validate-session.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | var User = require('sequelize').import('../models/user'); 3 | 4 | module.exports = function (req, res, next) { 5 | if (req.method == 'OPTIONS') { 6 | next(); // allowing options as a method for request 7 | } else { 8 | var sessionToken = req.headers.authorization; 9 | console.log(sessionToken); 10 | if (!sessionToken) return res.status(403).send({ auth: false, message: "No token provided." }); 11 | else { 12 | jwt.verify(sessionToken, 'lets_play_sum_games_man', (err, decoded) => { 13 | if (decoded) { 14 | User.findOne({ where: { id: decoded.id } }).then(user => { 15 | req.user = user; 16 | console.log(`user: ${user}`) 17 | next() 18 | }, 19 | function () { 20 | res.status(401).send({ error: "not authorized" }); 21 | }) 22 | 23 | } else { 24 | res.status(400).send({ error: "not authorized" }) 25 | } 26 | }); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /models/game.js: -------------------------------------------------------------------------------- 1 | function(sequelize, DataTypes) { 2 | return sequelize.define('game', { 3 | title: { 4 | type: DataTypes.STRING(25), 5 | allowNull: false, 6 | }, 7 | 8 | owner_id: { 9 | type: DataTypes.INTEGER, 10 | allowNull: false 11 | }, 12 | 13 | studio: { 14 | type: DataTypes.STRING, 15 | allowNull: false, 16 | }, 17 | 18 | esrb_rating: { 19 | type: DataTypes.CHAR(5), 20 | allowNull: false, 21 | }, 22 | 23 | user_rating: { 24 | type: DataTypes.INTEGER, 25 | allowNull: false, 26 | validate: { 27 | min: 1, 28 | max: 5 29 | } 30 | }, 31 | 32 | have_played : { 33 | type: DataTypes.BOOLEAN, 34 | defaultValue: false, 35 | allowNull: false 36 | } 37 | }) 38 | } -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | module.exports = function(sequelize, DataTypes) { 2 | return sequelize.define('user', { 3 | full_name: { 4 | type: DataTypes.STRING, 5 | allowNull: false 6 | }, 7 | 8 | username: { 9 | type: DataTypes.STRING, 10 | allowNull: false 11 | }, 12 | 13 | passwordHash: { 14 | type: DataTypes.STRING, 15 | allowNull: false 16 | }, 17 | 18 | email: { 19 | type: DataTypes.STRING, 20 | allowNull: false, 21 | validate: { 22 | isEmail: true 23 | } 24 | } 25 | }) 26 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "debug-challenge", 3 | "version": "1.0.0", 4 | "main": "app.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "bcryptjs": "^2.4.3", 8 | "body-parser": "^1.18.3", 9 | "express": "^4.16.4", 10 | "jsonwebtoken": "^8.3.0", 11 | "pg": "^7.6.0", 12 | "sequelize": "^4.41.0" 13 | }, 14 | "devDependencies": { 15 | "nodemon": "^1.18.5" 16 | } 17 | } 18 | --------------------------------------------------------------------------------