diff --git a/README.md b/README.md index 304a16f1..b5bb8e3f 100755 --- a/README.md +++ b/README.md @@ -1,89 +1,23 @@ -Assignment 2 - Short Stack: Basic Two-tier Web Application using HTML/CSS/JS and Node.js -=== - -Due: September 9th, by 11:59 AM. - -This assignment aims to introduce you to the concepts and practice involved in creating a prototype (i.e. not deployment ready) two-tiered web application. - -The baseline aims of this assignment involve creating an application that demonstrates the use of several specific pieces of HTML, CSS, JavaScript, and Node.js functionality. -Another aim of this assignment is to establish creative boundaries in which you and your partner can explore designing, implementing, and evaluating usable, useful, novel, and technically efficient web applications. - -Baseline Requirements ---- - -Note that there is a very large range of application areas and possibilities that meet these baseline requirements. -Games, internet of things, organizational tools, commerce, media - all are possibilities with a two-tiered form-focused web application. - -Do not limit yourselves to any of the examples given below. -Examples like the upcoming `efficiency_ratio` idea for the `cars` dataset are meant to be illustrative and easy to understand. -They are not intended to be sensible or useful ideas. - -Your application is required to implement the following functionalities: - -- a `Server` which not only serves files, but also maintains a tabular dataset with 3 or more fields related to your application -- a `Results` functionality which shows the entire dataset residing in the server's memory -- a `Form/Entry` functionality which allows a user to add, modify, or delete data items residing in the server's memory -- a `Server Logic` which, upon receiving new or modified "incoming" data, includes and uses a function that adds at least one additional derived field to this incoming data before integrating it with the existing dataset - - the `Derived field` for a new row of data must be computed based on fields already existing in the row. For example, a `cars` dataset with `year`, `horsepower`, and `fuel_efficiency` may create a new field `efficiency_ratio` by dividing `fuel_efficiency` by `horsepower` - -Your application is required to demonstrate the use of the following concepts: - -HTML: -- One or more [HTML Forms](https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms), with any combination of form tags appropriate for the user input portion of the application - - Clarification: the results page can be implemented in any way. `
`s, `table`s, and `list`s are common choices - -CSS: -- CSS styling of the primary visual elements in the application -- Various CSS Selector functionality must be demonstrated: - - Element selectors - - ID selectors - - Class selectors -- CSS positioning and sizing of the primary visual elements in the application: - - CSS to cause at least one element to be horizontally centered on the page - - CSS to cause at least one pair of elements to appear side-by-side - - CSS defined in a maintainable, readable form, in external stylesheets - -JavaScript: -- At minimum, a small amount of front-end JavaScript to get / fetch data from the server; a sample is provided in this repository. - -Node.js: -- An HTTP Server that delivers all necessary files and data for the application. A starting point is provided in this repository. - -Deliverables +README --- -Do the following to complete this assignment: - -1. Fork the starting project code. This repo contains some starter code that may be used or discarded as needed. -2. Implement your project with the above requirements. -3. Test your project to make sure that when someone goes to your main page, it displays correctly. -4. Deploy your project to Glitch, and fill in the appropriate fields in your package.json file. -5. Ensure that your project has the proper naming scheme `a2-yourname` so we can find it. -6. Modify the Readme to the specifications below. -7. Create and submit a Pull Request to the original repo. Label the pull request as follows: a2-gitusername-firstname-lastname - -Sample Readme (delete the above when you're ready to submit, and modify the below so with your links and descriptions) ---- - -## Your Web Application Title -Include a very brief summary of your project here. -Images are encouraged, along with concise, high-level text. - -Here is a sample formula for summarizing your activities, talk about: -- the domain area the project pertains to -- the main challenges or problems the application addresses -- the key innovations that make it possible to address the problem -- the main results of the implementation, does it really address the problem? -- any additional implications of the resulting application, or possibly areas for future work that have been discovered as part of the design and implementation activities +## Basic User System +This is a basic user management system, allowing for people to create accounts, and allowing admins to delete accounts. -(Note that when I use the above formula, I aim to have only one sentence per thought in order to remain concise.) +In this application, I: +- was able to get the front end to retrieve data from the server +- was able to get the front end to send data to the server +- was able to add and delete users to the server -http://a2-charlieroberts.glitch.me +http://a2-dannyjsullivan.glitch.me ## Technical Achievements -- **Tech Achievement 1**: Using a combination of... -- **Tech Achievement 2**: ... +- **Tech Achievement 1**: created a login system that does not allow duplicate users (users with the same username) +- **Tech Achievement 2**: created a function to show the password to the user +- **Tech Achievement 3**: created a basic encryption function to prevent the admin from reading the passwords (i couldn't get a toggle working to flip from encrypted to unencrypted, but you can just change the encrypt flag in "loggedin_admin.html" to "false" in order to ensure it is working properly) ### Design/Evaluation Achievements -- **Design Achievement 1**: Shown in `style.css`, the code... -- **Design Achievement 2**: We tested the application with n=X users, finding that... +- **Design Achievement 1**: changed the color and format of text, background, and objects to try and make it more readable +- **Design Achievement 2**: changed the form input boxes to have placeholders so that you do not have to delete already existing text +- **Design Achievement 3**: created several pop up windows so the user can see the result of an action from a data response to see the outcome of an action +- **Design Achievement 3**: used adobe color wheel to find a color scheme that worked \ No newline at end of file diff --git a/package.json b/package.json index 988f135f..8f95fc6a 100755 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "start": "node server.improved.js" }, "dependencies": { + "bcrypt": "^3.0.6", + "firebase-tools": "^7.3.1", "mime": "^2.4.4" } } diff --git a/public/css/style.css b/public/css/style.css index d5f842ab..35406a8f 100755 --- a/public/css/style.css +++ b/public/css/style.css @@ -1 +1,83 @@ -/*Style your own assignment! This is fun! */ \ No newline at end of file +/*Style your own assignment! This is fun! */ +body { + background-color: #D4E8FF; +} + +h1 { + color: #353A40; + font-family: sans-serif; +} + +h2 { + color: #353A40; + font-family: sans-serif; +} + +h3 { + color: #353A40; + font-family: sans-serif; +} + +button { + font-family: sans-serif; + display: inline-block; + padding: 2px; + padding-left: 5px; + padding-right: 5px +} + +button:hover { + font-family: sans-serif; + display: inline-block; + padding: 2px; + padding-left: 5px; + padding-right: 5px; + background-color: #6A7480; + color: #D4E8FF; +} + +a { + color: #848484; + font-family: sans-serif; +} + +input { + margin: 1%; + font-family: sans-serif; +} + +td:hover { + background-color: #9FAEBF; +} + +tr { + background-color: #9FAEBF; +} + +th { + margin-top: 5%; + border: 1px solid black; + color: #353A40; + border-collapse: collapse; +/* width: 40%; */ + padding-left: 20px; + padding-right: 20px; + padding-top: 5px; + padding-bottom: 5px; + text-align: center; + font-family: sans-serif; +} + +table, td { + margin-top: 5%; + border: 1px solid black; + color: #353A40; + border-collapse: collapse; +/* width: 40%; */ + padding-left: 20px; + padding-right: 20px; + padding-top: 5px; + padding-bottom: 5px; + text-align: center; + font-family: sans-serif; +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index c56d620e..35ed455c 100755 --- a/public/index.html +++ b/public/index.html @@ -1,23 +1,46 @@ + CS4241 Assignment 2 +
+

Login

- - + +
+ +
+ show password +
+
+ create new account +
+

+ diff --git a/public/loggedin_admin.html b/public/loggedin_admin.html new file mode 100644 index 00000000..dfb51dee --- /dev/null +++ b/public/loggedin_admin.html @@ -0,0 +1,218 @@ + + + + + CS4241 Assignment 2 + + + +
+

Congrats! You logged in as an admin!

+
+ +
+ +
+ +
+
UsernamePasswordAdmin?
+
+ + + diff --git a/public/register.html b/public/register.html new file mode 100644 index 00000000..511d4b4e --- /dev/null +++ b/public/register.html @@ -0,0 +1,77 @@ + + + + + CS4241 Assignment 2 + + + +

+
+

Register

+
+ +
+ +
+ +
+ show password(s) +
+ +
+ already have account? +
+ + + diff --git a/server.improved.js b/server.improved.js index 26673fc0..b78ffd68 100644 --- a/server.improved.js +++ b/server.improved.js @@ -1,5 +1,6 @@ const http = require( 'http' ), fs = require( 'fs' ), + bcrypt = require('bcrypt'), // 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' ), @@ -7,9 +8,10 @@ const http = require( 'http' ), port = 3000 const appdata = [ - { 'model': 'toyota', 'year': 1999, 'mpg': 23 }, - { 'model': 'honda', 'year': 2004, 'mpg': 30 }, - { 'model': 'ford', 'year': 1987, 'mpg': 14} + { 'username': 'user', 'password': 'pass', 'admin': "false" }, + { 'username': 'test', 'password': 'test', 'admin': "false" }, + { 'username': 'abc', 'password': '123', 'admin': "false" }, + { 'username': 'admin', 'password': '', 'admin': "true"} ] const server = http.createServer( function( request,response ) { @@ -22,15 +24,91 @@ const server = http.createServer( function( request,response ) { const handleGet = function( request, response ) { const filename = dir + request.url.slice( 1 ) + + console.log(request.url) if( request.url === '/' ) { sendFile( response, 'public/index.html' ) - }else{ + } + else if(request.url === '/style.css') { + sendFile( response, 'public/css/style.css' ) + } + else{ sendFile( response, filename ) } } +function login(username, password) { + for(var i = 0; i < Object.keys(appdata).length; i++) { + let j = i; + console.log(username + " vs. " + appdata[j].username) + if(username == appdata[j].username) { + if(password == appdata[j].password) { + return true; + } + else { + console.log("wrong password!") + } + } + } + return false; +} + +var newUserStatus = "" + +function newUser(username, password) { + for(var i = 0; i < Object.keys(appdata).length; i++) { + let j = i; + console.log(username + " vs. " + appdata[j].username) + if(username == appdata[j].username) { + console.log("cannot make new user! username already taken.") + newUserStatus = "cannot make new user! username already taken." + return -1; + } + } + console.log("new user created!") + newUserStatus = "new user created!" + appdata.push({username: username, password: password, admin: "false"}) +} + +function deleteUser(username, password) { + for(var i = 0; i < Object.keys(appdata).length; i++) { + let j = i; + console.log("deleting user: " + username) + if(username == appdata[j].username) { + console.log("deleting user") + delete appdata[j].username + delete appdata[j].password + delete appdata[j].admin + } + else { + console.log("could not find user!") + } + } +} + +function updateUser(username) { + for(var i = 0; i < Object.keys(appdata).length; i++) { + let j = i; + console.log("updating user: " + username) + if(username == appdata[j].username) { + console.log("updating user") + if(appdata[j].admin == "false") { + appdata[j].admin = "true" + } + else { + appdata[j].admin = "false" + } + } + else { + console.log("could not find user!") + } + } +} + const handlePost = function( request, response ) { + console.log("received post!") + let dataString = '' request.on( 'data', function( data ) { @@ -38,12 +116,64 @@ const handlePost = function( request, response ) { }) request.on( 'end', function() { - console.log( JSON.parse( dataString ) ) + + var data=JSON.parse(dataString) + + console.log( data ) // ... do something with the data here!!! - - response.writeHead( 200, "OK", {'Content-Type': 'text/plain' }) - response.end() + + var resp = "" + var isAdmin = "false" + + if(data.action == "login") { + console.log("trying to log in.") + if(login(data.username, data.password)) { + resp = "logged in successfully!" + if(data.username == "admin") { + isAdmin = "true" + } + console.log("logged in successfully!") + } + else { + resp = "unable to log in!" + console.log("unable to log in!") + } + } + else if(data.action == "add") { + console.log("add command") + newUser(data.username, data.password) + } + else if(data.action == "delete") { + console.log("delete command") + deleteUser(data.username, data.password) + } + else if(data.action == "update") { + console.log("update command") + updateUser(data.username) + } + + // var fake_json = { "loginStatus": login(username, password), "users": appdata } + + if(isAdmin === "true") { + var json_resp = {"loginstatus": resp, "adminstatus": isAdmin, users: appdata} + } + else { + var json_resp = {"loginstatus": resp, "adminstatus": isAdmin} + } + + if(data.action == "add") { + var json_resp = {"status": newUserStatus} + } + + // make response json format, but sauce it over as plaintext. if we do that, then we convert it + // from plaintext to json on the other boi then should be gg just make sure to fufill the other requirements + + response.writeHead( 200, "OK", {'Content-Type': 'text/plain'}) + // response.end(JSON.stringify(fake_json)) + response.end(JSON.stringify(json_resp)) + + console.log(json_resp) }) }