From 0e85fa878806abbc4da93491959381551cd4d041 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 15 Sep 2019 14:33:40 -0400 Subject: [PATCH 1/3] upload inital files --- .gitignore | 3 + package.json | 23 +++ public/css/style.css | 1 + public/data.json | 1 + public/index.html | 161 +++++++++++++++++++ public/js/scripts.js | 3 + public/login.html | 19 +++ server.improved.js | 361 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 572 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 public/css/style.css create mode 100644 public/data.json create mode 100644 public/index.html create mode 100644 public/js/scripts.js create mode 100644 public/login.html create mode 100644 server.improved.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..57195033 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.DS_Store +node_modules/ +package-lock.json diff --git a/package.json b/package.json new file mode 100644 index 00000000..9c431525 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "People Information Safe", + "version": "1.0.0", + "description": "store information about people on this website", + "author": "James Scherick", + "scripts": { + "start": "node server.improved.js" + }, + "dependencies": { + "body-parser": "^1.19.0", + "connect-ensure-login": "^0.1.1", + "cookie-parser": "^1.4.4", + "cookie-session": "^1.3.3", + "express": "^4.42.1", + "express-session": "^1.16.2", + "mime": "^2.4.4", + "modern-normalize": "^0.5.0", + "mongodb": "^3.3.2", + "morgan": "^1.9.1", + "passport": "^0.4.0", + "passport-local": "^1.0.0" + } +} diff --git a/public/css/style.css b/public/css/style.css new file mode 100644 index 00000000..d5f842ab --- /dev/null +++ b/public/css/style.css @@ -0,0 +1 @@ +/*Style your own assignment! This is fun! */ \ No newline at end of file diff --git a/public/data.json b/public/data.json new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/public/data.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 00000000..df4a6478 --- /dev/null +++ b/public/index.html @@ -0,0 +1,161 @@ + + + + + CS4241 Assignment 2 + + + +
+ + + + + + + + + + + +
Your Name Your Birthday Your Favorite Food
+ + +
+ + +
+ + + + diff --git a/public/js/scripts.js b/public/js/scripts.js new file mode 100644 index 00000000..de052eae --- /dev/null +++ b/public/js/scripts.js @@ -0,0 +1,3 @@ +// Add some Javascript code here, to run on the front end. + +console.log("Welcome to assignment 2!") \ No newline at end of file diff --git a/public/login.html b/public/login.html new file mode 100644 index 00000000..d22882d8 --- /dev/null +++ b/public/login.html @@ -0,0 +1,19 @@ + + + + +
+
+ + +
+
+ + +
+
+ +
+
+ + \ No newline at end of file diff --git a/server.improved.js b/server.improved.js new file mode 100644 index 00000000..eca91028 --- /dev/null +++ b/server.improved.js @@ -0,0 +1,361 @@ +const http = require( 'http' ), + fs = require( 'fs' ), + // IMPORTANT: you must run `npm install` in the directory for this assignment + // to install the mime library used in the following line of code + mime = require( 'mime' ), + dir = 'public/', + port = 3000 + +var passport = require('passport') + , LocalStrategy = require('passport-local').Strategy; +const express = require('express'); +const app = express(); + +//const bodyParser = require('body-parser'); +//app.use(bodyParser.urlencoded({ extended: true })); + +app.use(require('morgan')('combined')); +app.use(require('body-parser').urlencoded({ extended: true })); +app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false })); + +//app.use(bodyParser.urlencoded({ extended: false })); +app.use(passport.initialize()); +app.use(passport.session()); +passport.CreateSession = function (req, res, next) { + passport.authenticate('local', function(err, user, info){ + if(err || !user) + return res.json({status: "Failure: "+err}); + req.logIn(user, function (err){ + if(err) + return res.json({status: "Failure: "+err}); + return res.json({status: "Authenticated"}); + }); + })(req, res, next); +}; + +let Users = [{username: "test", password:"test2", id: 1} ]; +passport.serializeUser(function (user, done) { + + done(null, user.id); + console.log("user Serialized") +}); + +passport.deserializeUser(function(id, cb) { + console.log("user Deserialized") + let user = Users.find(function(element){return element.id == id}); + cb(null, user); + /*Users.findById(id, function(err, user) { + cb(err, user); + console.log("user Deserialized") + });*/ +}); +passport.use(new LocalStrategy( + function(username, password, done) { + let user = Users.find(function(element) { + return element.username == username && element.password == password; +}); + if (!user){ + return done(null, false, {message: "username or password not found"}); + } + return done(null, user); + } +)); + +app.post('/login', + passport.authenticate('local', { failureRedirect: '/error'}), + function(req, res) { + console.log('POST /login'); + console.log('req.session', req.session); + console.log('req.user', req.user); + // res.cookie('sessionKey', req.session); + res.redirect('/'); +// sessionStorage.setItem('user', req.session.user); + //req.session.save() + //sendFile( res, 'public/index.html' ) + }); + +app.get('/error', function(req, res){ + console.log('GET /error'); + res.send("username or password was incorrect") +}) + +app.get('/index.html', passport.authenticate('local', { failureRedirect: '/login' }), + function(req, res) { + sendFile( res, 'public/index.html' ) + return + }); +app.get('/', require('connect-ensure-login').ensureLoggedIn(), + function(req, res) { + console.log('GET /'); + console.log('req.user', req.user); + sendFile( res, 'public/index.html' ) + return + }); +app.get('/login', function (req, res) { + console.log('GET /login'); + sendFile(res, 'public/login.html') +}); +app.get('/getAll.json', function(req, res){ + getData(req, res); +}) +app.post('/submit', function(req, res){ + console.log(req.user) + handlePost(req, res) +}) +app.post('/edit', function(req, res){ + handleEdit(req, res) +}) +app.post('/deleteALL', function(req, res){ + handleDeleteAll(req, res) +}) +app.post('/deleteEntry', function(req, res){ + handleDelete(req, res) +}) + +const handleDeleteAll = function( request, response ) { + let dataString = '' + + request.on( 'data', function( data ) { + dataString += data + }) + + request.on( 'end', function() { + console.log( JSON.parse( dataString ) ) + + fs.readFile( "public/data.json", function( err, content ) { + + + // if the error = null, then we've loaded the file successfully + if( err === null ) { + const fs = require('fs') + fs.writeFile('public/data.json', "[]", (err) => { + if (err) throw err; + }) + + + + response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) + response.end() + + }else{ + + // file not found, error code 404 + response.writeHeader( 404 ) + response.end( '404 Error: File Not Found' ) + + } + }) + + + }) +} +const handleDelete = function( request, response ) { + let dataString = '' + + request.on( 'data', function( data ) { + dataString += data + }) + + request.on( 'end', function() { + console.log( JSON.parse( dataString ) ) + + fs.readFile( "public/data.json", function( err, content ) { + + + // if the error = null, then we've loaded the file successfully + if( err === null ) { + let index = JSON.parse(dataString).delete; + console.log(dataString); + let data = JSON.parse(content); + data.splice(index, 1); + + + + + const fs = require('fs') + fs.writeFile('public/data.json', JSON.stringify(data), (err) => { + if (err) throw err; + }) + + + + response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) + response.end() + + }else{ + + // file not found, error code 404 + response.writeHeader( 404 ) + response.end( '404 Error: File Not Found' ) + + } + }) + + + }) +} + +const handleEdit = function( request, response ) { + let dataString = '' + + request.on( 'data', function( data ) { + dataString += data + }) + + request.on( 'end', function() { + console.log( JSON.parse( dataString ) ) + + fs.readFile( "public/data.json", function( err, content ) { + + + // if the error = null, then we've loaded the file successfully + if( err === null ) { + let age = calculateAge(new Date(JSON.parse(dataString).date)); + let newData = JSON.parse(dataString); + newData.age = age; + let newerData = {name: newData.name, date: newData.date, food: newData.food, age : newData.age}; + let data = JSON.parse(content); + console.log(JSON.stringify(data)); + data[newData.index] = newerData; + console.log(JSON.stringify(data)); + + + + + const fs = require('fs') + fs.writeFile('public/data.json', JSON.stringify(data), (err) => { + if (err) throw err; + }) + + + + response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) + response.end() + + }else{ + + // file not found, error code 404 + response.writeHeader( 404 ) + response.end( '404 Error: File Not Found' ) + + } + }) + + + }) +} + +const handlePost = function( request, response ) { + let dataString = '' + + request.on( 'data', function( data ) { + dataString += data + }) + + request.on( 'end', function() { + console.log( JSON.parse( dataString ) ) + + fs.readFile( "public/data.json", function( err, content ) { + + + // if the error = null, then we've loaded the file successfully + if( err === null ) { + let age = calculateAge(new Date(JSON.parse(dataString).date)); + let newData = JSON.parse(dataString); + newData.age = age; + let data = JSON.parse(content); + console.log(JSON.stringify(data)); + data.push(newData); + console.log(JSON.stringify(data)); + + + + + const fs = require('fs') + fs.writeFile('public/data.json', JSON.stringify(data), (err) => { + if (err) throw err; + }) + + + + response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) + response.end() + + }else{ + + // file not found, error code 404 + response.writeHeader( 404 ) + response.end( '404 Error: File Not Found' ) + + } + }) + + + }) +} + function calculateAge(birthday) { + var ageDifMs = Date.now() - birthday.getTime(); + var ageDate = new Date(ageDifMs); + return ageDate.getUTCFullYear() - 1970; + } + +const sendFile = function( response, filename ) { + const type = mime.getType( filename ) + + fs.readFile( filename, function( err, content ) { + + // if the error = null, then we've loaded the file successfully + if( err === null ) { + + // status code: https://httpstatuses.com + response.writeHeader( 200, { 'Content-Type': type }) + response.end( content ) + + }else{ + + // file not found, error code 404 + response.writeHeader( 404 ) + response.end( '404 Error: File Not Found' ) + + } + }) +} + +const getData = function ( request, response ) { + const type = mime.getType( "public/data.json" ) + + fs.readFile( "public/data.json", function( err, content ) { + let i = 0; + + + // if the error = null, then we've loaded the file successfully + if( err === null ) { + let res = "

hello "+ (request.user && request.user.username ? request.user.username : "undefined") +"

"; + const data = JSON.parse(content); + data.forEach(function(d) { + res += ""; + i++; + }); + res += "
namebirthdayfavorite foodagedelete entryedit
" + d.name + "" + d.date + "" + d.food + "" + d.age + "
"; + + // status code: https://httpstatuses.com + response.writeHead(200, {"Content-Type": "text/html"}); + response.end( res ) + + }else{ + + // file not found, error code 404 + response.writeHeader( 404 ) + response.end( '404 Error: File Not Found' ) + + } + }) +} + + +//server.listen( process.env.PORT || port ) + + +app.listen(3000, function () { + console.log('Ready') +}) \ No newline at end of file From b663b5bf3dd7700353c0c1ff7ce61957535dd0b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 15 Sep 2019 19:00:06 -0400 Subject: [PATCH 2/3] finished the project --- README.md | 83 +++---------- package.json | 8 +- public/css/style.css | 1 - public/data.json | 2 +- public/index.html | 136 +++++++++------------- public/js/scripts.js | 3 - public/login.html | 2 +- public/loginDetails.json | 1 + server.improved.js | 245 +++++++++++++-------------------------- 9 files changed, 155 insertions(+), 326 deletions(-) delete mode 100644 public/css/style.css delete mode 100644 public/js/scripts.js create mode 100644 public/loginDetails.json diff --git a/README.md b/README.md index afcca619..b59215ae 100755 --- a/README.md +++ b/README.md @@ -1,74 +1,21 @@ -Assignment 3 - Persistence: Two-tier Web Application with Flat File Database, Express server, and CSS template -=== +## Food You Eat -Due: September 16th, by 11:59 AM. +https://a3-jamesscherick.glitch.me -This assignnment continues where we left off, extending it to use the most popular Node.js server framework (express), a flat file database suitable for small applications (lowdb), and a CSS application framework / template of your choice (Boostrap, Material Design, Semantic UI, Pure etc.) +![What the website looks like after logging in](https://github.com/jimmyjam100/a3-persistence/blob/master/image.PNG) +The goal of this application is to have a place where everyone can have a personal list of all of the different types of food they eat so they can keep track of their diet. +To log in enter any unused username to create a new account, or use an existing username and password. +It took me many many hours to figure out how the authentification process worked. I would redirect to the home page and then be redirected right back because the login session did not save. Turned out I needed to add more middleware that I did not know about. +The authentification stratagy I used was just local, and for database I ended up just writing and reading from a json file for my database. That is bassically what lowDB does and I am more comfturable doing it like this. +I chose to use the pure css framework. I feel like its style really fit my theme of just a place you can list things without being to fancy or anything. It just felt clean. I also like how they do tables +I used passport, morgan, session, body-parser, and express-uncapitalize. +passport is used for authenticating users and creating a login system. +morgan is used for logging any get and post request that are made to the server. Used for debugging +session stores your login information for the duration of the session. +express-uncapitalize uncapitalizes any url you have by redirecting you to the url that is not capitalized -Baseline Requirements ---- - -Your application is required to implement the following functionalities: - -- a `Server`, created using Express (no alternatives will be accepted for this assignment) -- a `Results` functionality which shows the entire dataset residing in the server's memory -- a `Form/Entry` functionality which allows users to add, modify, and delete data items (must be all three!) associated with their user name / account. -- Use of at least five [Express middleware packages](https://expressjs.com/en/resources/middleware.html). Explore! -- Basic authentication using the [Passport middleware](http://www.passportjs.org) for Express (this counts as one of your five middleware packages). We encourage using the Local strategy, but OAuth (Open Authentication) can also be used for additional technical achievement. The course staff cannot help you with the various flavors of OAuth strategies. YOU MUST PROVIDE US WITH ACCOUNT CREDENTIALS TO LOGIN TO YOUR APPLICATION IF YOU USE OAUTH. The course staff cannot be expected to have credentials for any particular OAuth service. -- Persistent data storage in between server sessions. [lowdb](https://github.com/typicode/lowdb) is a suitable database package for this assignment and will be discussed in class. -- Use of a [CSS framework or template](https://github.com/troxler/awesome-css-frameworks). This should do the bulk of your styling/CSS for you and be appropriate to your application. For example, don't use [NES.css](https://nostalgic-css.github.io/NES.css/) (which is awesome!) unless you're creating a game or some type of retro 80s site. - -Your application is required to demonstrate the use of the following concepts: - -HTML: -- HTML input tags and form fields of various flavors (`