Skip to content
Open

gsg #22

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
17a5696
login page - leo
zeolhu Nov 4, 2024
82b6616
Emily: Moved CSS to stylesheet, temp header and footer implemented
emsm2434 Nov 5, 2024
1cefbcf
fixed conflicting styling issues & put header inside body
so-po Nov 5, 2024
9e0385f
Update minutes.txt
emsm2434 Nov 5, 2024
7ac9ec8
Notes from TA meeting 11/5/2024
emsm2434 Nov 5, 2024
0b6fa8d
Emily: Database now functional
emsm2434 Nov 6, 2024
4bfa8c1
Merge branch 'main' into integrate_login_header_footer_separate_css
emsm2434 Nov 6, 2024
5799b96
Merge pull request #14 from onionSoap/integrate_login_header_footer_s…
emsm2434 Nov 6, 2024
f370180
register page -leo
zeolhu Nov 7, 2024
7a78527
Lab11 : Update project.json
emsm2434 Nov 7, 2024
f2680a3
Lab11: Update docker-compose.yaml
emsm2434 Nov 7, 2024
b8f1fd0
Lab11: Started test file
emsm2434 Nov 7, 2024
0e5f753
Lab11: Update index.js
emsm2434 Nov 7, 2024
c85159d
Lab11: Added basic add_user tests from lab writeup
emsm2434 Nov 7, 2024
71b29d9
Lab11: Updating descriptions
emsm2434 Nov 7, 2024
a5f9aa9
Emily: Added register get/post
emsm2434 Nov 7, 2024
fa18965
Lab11: Create account tests added
emsm2434 Nov 7, 2024
e3d1ed6
Emily: Updated register check
emsm2434 Nov 7, 2024
f1ff5df
Emily: Added dummy code for page3 for index.js get call
emsm2434 Nov 7, 2024
607c616
Emily: Added page3 get call
emsm2434 Nov 7, 2024
7a155b8
SVG's for scene 1 & 2, WIP
so-po Nov 8, 2024
7d8e310
Small edits to svg's for gameplay
so-po Nov 8, 2024
faf0b1e
SVG Palooza, even more svg's
so-po Nov 9, 2024
fab32a9
Simpler svg's (no inkscape bloat)
so-po Nov 9, 2024
ae90e5a
Emily: Post for update_item_status
emsm2434 Nov 11, 2024
a329381
Uploading test plan + changing default docker command from 'test' to …
so-po Nov 11, 2024
91f9984
Emily: Reformatted meeting logs
emsm2434 Nov 11, 2024
d5b3b06
Emily: Deleted minutes.txt because it's redundant now
emsm2434 Nov 11, 2024
4026b72
Emily: Temp Register Page added, registration works, login works, log…
emsm2434 Nov 11, 2024
2bd0466
Emily: Login working, Register working, Logout working (and restricti…
emsm2434 Nov 11, 2024
258418a
Merge pull request #17 from onionSoap/working_on_get_post_in_index.js
emsm2434 Nov 11, 2024
fc94002
Minutes for meeting nov 12
so-po Nov 12, 2024
95c6c1c
Actual minutes
so-po Nov 12, 2024
f7f340d
Minutes not in rtf, txt instead
so-po Nov 12, 2024
dd1d25b
Emily: More tests added + fixed update_item_status tests failing
emsm2434 Nov 13, 2024
f0c7642
Merge pull request #20 from onionSoap/working_on_get_post_in_index.js
emsm2434 Nov 13, 2024
7376a37
Fixed meeting4 text
so-po Nov 14, 2024
0f0cea7
Merge branch 'login-leo' into main
zeolhu Nov 14, 2024
8d5618a
Fix YAML file
so-po Nov 14, 2024
fbccc61
Fix yaml 2
so-po Nov 14, 2024
2009744
Merge branch 'dorjee' into dorjee1
dorjeezzz Nov 14, 2024
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
Binary file not shown.
Binary file not shown.
7 changes: 7 additions & 0 deletions ProjectSourceCode/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# database credentials
POSTGRES_USER="postgres"
POSTGRES_PASSWORD="pwd"
POSTGRES_DB="users_db"

# Node vars
SESSION_SECRET="super duper secret!"
7 changes: 4 additions & 3 deletions ProjectSourceCode/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
version: '3.9'
services:
db:
#these are containers
db: #this is for the database
image: postgres:14
#env_file: .env
expose:
- '5432'
volumes:
- group-project:/var/lib/postgresql/data
- ./src/init_data:/docker-entrypoint-initdb.d
web:
web: #this is for the website
image: node:lts
user: 'node'
working_dir: /repository
Expand All @@ -21,6 +22,6 @@ services:
- '3000:3000'
volumes:
- ./:/repository
command: 'npm start'
command: 'npm run start'
volumes:
group-project:
43 changes: 26 additions & 17 deletions ProjectSourceCode/package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
{
"name": "node-ejs",
"main": "index.js",
"dependencies": {
"ejs": "^2.5.5",
"ejs-lint": "^0.3.0",
"body-parser": "^1.20.0",
"express": "^4.6.1",
"express-session": "^1.17.3",
"express-handlebars": "^7.1.2",
"pg-promise": "^10.11.1",
"nodemon": "2.0.20"
},
"scripts": {
"prestart": "npm install",
"start": "nodemon src/index.js"
}
}
"name": "SoftwareDevTeamProject",
"main": "src/index.js",
"dependencies": {
"express": "^4.6.1",
"pg-promise": "^10.11.1",
"body-parser": "1.20.0",
"express-session": "1.17.3",
"express-handlebars": "^7.1.2",
"handlebars": "^4.7.8",
"axios": "^1.1.3",
"bcryptjs": "^2.4.0"
},
"devDependencies": {
"nodemon": "^2.0.7",
"mocha": "^6.2.2",
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"npm-run-all": "^4.1.5"
},
"scripts": {
"prestart": "npm install",
"start": "nodemon index.js",
"test": "mocha",
"testandrun": "npm run prestart && npm run test && npm start"
}
}
232 changes: 171 additions & 61 deletions ProjectSourceCode/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,105 +3,215 @@ const express = require('express');
const app = express();
const handlebars = require('express-handlebars');
const path = require('path');
const pgp = require('pg-promise')();
const pgp = require('pg-promise')(); //library that gives me access to make any database that i have access to normally
const bcrypt = require('bcryptjs'); // To hash passwords
const bodyParser = require('body-parser');
const session = require('express-session');
const { getBuiltinModule } = require('process');

// ------------------------------------- APP CONFIG ----------------------------------------------

// create `ExpressHandlebars` instance and configure the layouts and partials dir.
const hbs = handlebars.create({
extname: 'hbs',
layoutsDir: path.join(__dirname, 'views/layouts'),
partialsDir: [
path.join(__dirname, 'views/partials'),
path.join(__dirname, 'views/partials/svg_components')
],
helpers: {
range: function(start, end, options) {
let result = '';
for (let i = start; i < end; i++) {
result += options.fn(i);
}
return result;
}
}
layoutsDir: __dirname + '/views/layouts',
partialsDir:[
__dirname + '/views/partials',
__dirname + '/views/partials/svg_components'
]
});
// ------------------------------------- DB CONFIG AND CONNECT ---------------------------------------
//TODO: Use this later for setting up db!
//accessed by either: hosted by another entity (need to have the url to access that)
//hosted outself, create two docker containers that runs the application and the other the database
const dbConfig = {
host: 'db',
port: 5432,
database: process.env.POSTGRES_DB,
user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
};
const db = pgp(dbConfig);


//// db test
db.connect()
.then(obj => {
// Can check the server version here (pg-promise v10.1.0+):
console.log('Database connection successful');
obj.done(); // success, release the connection;
})
.catch(error => {
console.log('ERROR', error.message || error);
});

// Register `hbs` as our view engine using its bound `engine()` function.
app.engine('hbs', hbs.engine);
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, 'views'));

// Static and session configuration
app.use(bodyParser.json());
// OHs this should fix my style.css inaccessibility issue
app.use('/resources', express.static(path.join(__dirname, 'resources')));
// set Session
app.use(
session({
secret: "super duper secret!", // Consider moving this to .env as process.env.SESSION_SECRET
secret: "super duper secret!", //TODO: they might want us to put this in an env file, like: process.env.SESSION_SECRET
saveUninitialized: true,
resave: true,
})
);
app.use(bodyParser.urlencoded({ extended: true }));

// ------------------------------------- DB CONFIG AND CONNECT ---------------------------------------
const dbConfig = {
host: 'db',
port: 5432,
database: process.env.POSTGRES_DB,
user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
};
const db = pgp(dbConfig);

// Routes
app.get('/page1', (req, res) => {
res.render('pages/page1');
});
app.use(
bodyParser.urlencoded({
extended: true,
})
);

app.get('/page2', (req, res) => {
res.render('pages/page2');
app.get('/welcome', (req, res) => {
res.json({status: 'success', message: 'Welcome!'});
});

app.get('/', (req, res) => {
res.redirect('/login');
res.redirect('/login'); //this will call the /anotherRoute route in the API
});

app.get('/login', (req, res) => {
res.render('pages/login');
});

app.get('/scoreboard', (req, res) => {
res.render('pages/scoreboard');
});
app.post('/login', async (req, res) => {
// console.log('login post accessed')
const username = req.body.username
const password = req.body.password
const hash = await bcrypt.hash(password, 10);
// console.log("Hashed password:", hash)
const sqlUsername = "SELECT * FROM users WHERE username = $1;"

try{
//async + await make it so that I don't need to do .then(data etc..) which makes the code cleaner and work more efficiently.
const user = await db.one(sqlUsername, [username])
const match = await bcrypt.compare(password, user.password)

//looks like there's a space for some reason? Why tho...?
// console.log("Username is:", username, ", Other username is:", user.username);
// console.log("Password is: ", password, ", Other password is: ", user.password)
// console.log("Matched as:", match);
// rest is mine from earlier
if(match){
// if (user.password == password && user.username == username){
// console.log("if statement")
req.session.user = user;
req.session.save();
res.status(200);
res.redirect('/page1')
}

else{
// console.log("else statement")
// If the password is incorrect, render the login page and send a message to the user stating "Incorrect username or password."
res.render('pages/login', {message:"Incorrect username or password.", error:true})
// res.render('/login')
}
}
catch{
console.log("User doesn't exist! Try registering.")
res.redirect('/register')
}
})

app.get('/inventory', (req, res) => {
res.render('pages/inventory');
//register
app.get('/register', (req, res) => {
res.render('pages/register');
});

app.post('/login', async (req, res) => {
//from lab 8
app.post('/register', async (req, res) => {
//hash the password using bcrypt library
const hash = await bcrypt.hash(req.body.password, 10);

// DONE: Insert username and hashed password into the 'users' table
const username = req.body.username;
const password = req.body.password;
const sqlUsername = "SELECT * FROM users WHERE username = $1;";
// console.log(username, password, hash);
//the rest of the information in the users table is auto generated
const sqlRegister = "INSERT INTO users (username, password) VALUES ($1, $2);" ;//removed returning *

try {
const user = await db.one(sqlUsername, [username]);
const match = await bcrypt.compare(password, user.password);
if (match) {
req.session.user = user;
req.session.save();
res.redirect('/discover');
} else {
res.render('pages/login', {message: "Incorrect username or password.", error: true});
}
} catch {
console.log("User doesn't exist! Try registering");
res.redirect('/register');
db.none(sqlRegister, [username, hash]) //changed any to none
/*
Redirect to GET /login route page after data has been inserted successfully.
If the insert fails, redirect to GET /register route.
*/
.then(data => {
// console.log("Registered user with: ", data)
//res.redirect('/login', {message:"Error discovering data.", error:true})
// res.json({status: 'success'});
res.status(200).render('pages/register', {message: "Registration Successful!"});
// res.redirect('/login', {message:"Registration Successful!"});
// res.redirect('/login');
})
.catch(function (err) {
res.status(400).render('pages/register', {message: "Registration Error!", error: true});
// res.redirect('/register', {message:"Registration Error!", error: true});
});
});

app.post('/update_item_status', async (req, res) => {
const {item_id, new_status} = req.body;
// console.log("Req.body in post req: ",req.body);
//try to update the item status
try{
const sql_item_update = 'UPDATE items SET status = $1 WHERE item_id = $2 RETURNING *';
//call update with db.one and the new_status and item_id that we want to update
db.one(sql_item_update, [new_status, item_id])
//do we need the data? just put it because I always do.
//also, don't reload the page bc tehre's no need (I think? We dont' want to have to refresh the page everytime we click an item)
.then(data => {
res.status(200).send({message:"Item status updated successfully!"});
// console.log('Item_id: ', item_id, " and new_status: ", new_status);
})
//reload the page with the error message pop-up
.catch(function (err) {
res.status(400).json({message:"Item Status Update Error!"});
// res.redirect('/page2');
});
}
//error if unable to
catch (error){
console.error('Error updating item status: ', error);
res.status(400).send({error: 'Failed to update item status.'});
}
})

// Authentication Middleware.
const auth = (req, res, next) => {
// console.log(req.session)
if (!req.session.user) {
// Default to login page.
return res.redirect('/login');
}
next();
};

// Authentication Required
app.use(auth);

app.get('/page1', (req, res) => {
res.render('pages/page1'); //this will call the /anotherRoute route in the API
});

app.get('/page2', (req, res) => {
res.render('pages/page2'); //this will call the /anotherRoute route in the API
});

// Start the server
app.listen(3000, () => {
console.log('Server is listening on port 3000');
app.get('/page3', (req, res) => {
res.render('pages/page3'); //this will call the /anotherRoute route in the API
});


app.get('/logout', (req, res) => {
req.session.destroy()
res.status(200);
res.render('pages/login', {message:"Logged out successfully!", error:false})
});

module.exports = app.listen(3000);
console.log('Server is listening on port 3000');
Loading