added documentary

This commit is contained in:
j.mei7
2022-03-26 15:52:33 +01:00
parent 1f38925581
commit f674415814
2 changed files with 187 additions and 194 deletions

227
index.js
View File

@@ -1,85 +1,77 @@
const express = require('express') // Import Packages
const mysql_handler = require("./mysql_handler") const express = require('express');
const bcrypt = require("bcryptjs") const bcrypt = require("bcryptjs");
const cookieParser = require("cookie-parser") const cookieParser = require("cookie-parser");
const jwt = require("jsonwebtoken") const jwt = require("jsonwebtoken");
const bodyParser = require("body-parser") const bodyParser = require("body-parser");
const app = express()
const uuid = require("uuid"); const uuid = require("uuid");
const port = 3000
const SECRET_KEY = "KEY" // Import Modules
const mysql_handler = require("./mysql_handler");
app.set("view engine", "ejs") // Global Variables
const app = express();
const port = 3000;
const SECRET_KEY = "KEY";
// Express App Setup
app.set("view engine", "ejs");
app.use(express.json()); app.use(express.json());
app.use(express.urlencoded({ extended: true})); app.use(express.urlencoded({ extended: true}));
app.use(cookieParser()); app.use(cookieParser());
app.use(bodyParser.json()) app.use(bodyParser.json());
app.use(express.static(__dirname + "/static")); app.use(express.static(__dirname + "/static"));
/* // Authentication Handlers
const authcookie = req.cookies.authcookie; // Check if user is authenticated and redirect to login if not
if(!authcookie){
return false;
}
jwt.verify(authcookie, SECRET_KEY, (err, data) =>{
if(err){
return false;
} else if(data.user){
return true;
}
})
*/
function authenticatedHandler(req, res, next){ function authenticatedHandler(req, res, next){
const authcookie = req.cookies.authcookie; const authcookie = req.cookies.authcookie; // Get authcookie from cookie
jwt.verify(authcookie, SECRET_KEY, (err, data) =>{ jwt.verify(authcookie, SECRET_KEY, (err, data) =>{ // Verify authcookie
if(err){ if(err){ // If authcookie is invalid
console.log(err) console.log(err);
res.redirect("/login") res.redirect("/login");
} else if(data.user){ } else if(data.user){ // If authcookie is valid
req.user = data.user; req.user = data.user; // Set user to data.user
mysql_handler.con.query(`SELECT * FROM users WHERE id = "${req.user}"`, function(err, result){ mysql_handler.con.query(`SELECT * FROM users WHERE id = "${req.user}"`, (err, result) => { // Get user from database
if(err) console.log(err); if(err) console.log(err);
let user = JSON.parse(JSON.stringify(result))[0]; let user = JSON.parse(JSON.stringify(result))[0]; // Parse user from database
req.isAdmin = user.isAdmin // Set user to req.user
req.username = user.username req.isAdmin = user.isAdmin;
req.firstname = user.firstname req.username = user.username;
req.lastname = user.lastname req.firstname = user.firstname;
next(); req.lastname = user.lastname;
next(); // Continue to next handler
}); });
} }
}) });
} }
function notAuthenticatedHandler(req, res, next){ // Check if user is not authenticated and redirect to home if so
const authcookie = req.cookies.authcookie; function notAuthenticatedHandler(req, res, next){
const authcookie = req.cookies.authcookie; // Get authcookie from cookie
jwt.verify(authcookie, SECRET_KEY, (err, data) =>{ jwt.verify(authcookie, SECRET_KEY, (err, data) =>{ // Verify authcookie
if(err){ if(err){ // If authcookie is invalid
console.log(err) console.log(err);
next(); next(); // Continue to next handler
} else if(data.user){ } else if(data.user){ // If authcookie is valid
res.redirect("/") res.redirect("/");
} }
}) });
} }
app.get("/", authenticatedHandler, (req, res) => { // Homepage
app.get("/", authenticatedHandler, (req, res) => {
let dict = { let dict = {
title: "Hallo", title: "Hallo",
isAdmin: req.isAdmin isAdmin: req.isAdmin
} }
res.render('index', dict) res.render('index', dict)
}) });
// Product Page
app.get("/product/:productId", (req, res) => { app.get("/product/:productId", (req, res) => {
let productId = req.params.productId; let productId = req.params.productId;
console.log(productId); console.log(productId);
@@ -94,8 +86,9 @@ app.get("/product/:productId", (req, res) => {
} }
res.render('product', dict) res.render('product', dict)
}); });
}) });
// Search Page
app.get("/search", (req, res) => { app.get("/search", (req, res) => {
var products = [ var products = [
{ {
@@ -136,18 +129,19 @@ app.get("/search", (req, res) => {
res.render('search', dict) res.render('search', dict)
}); });
}) });
// Order // Order Page
app.get("/order/:productId/:quantity/", authenticatedHandler, (req, res) => { app.get("/order/:productId/:quantity/", authenticatedHandler, (req, res) => {
let error = "" let error = "";
mysql_handler.con.query(`SELECT * FROM products WHERE id=${req.params.productId}`, function(err, result){ mysql_handler.con.query(`SELECT * FROM products WHERE id=${req.params.productId}`, function(err, result){ // Get product from database
if(err) throw err; if(err) throw err;
result = JSON.parse(JSON.stringify(result))[0];
if(req.params.quantity > result.quantity){ result = JSON.parse(JSON.stringify(result))[0]; // Parse result from database
error = "Nicht genug Produkte vorhanden"
if(req.params.quantity > result.quantity){ // If quantity is higher than available quantity
error = "Nicht genug Produkte vorhanden";
} }
let dict = { let dict = {
@@ -157,18 +151,21 @@ app.get("/order/:productId/:quantity/", authenticatedHandler, (req, res) => {
quantity: req.params.quantity quantity: req.params.quantity
} }
res.render('order', dict) res.render('order', dict);
}); });
}) });
// Order Success Page
app.get("/order_success/:trackingnumber", authenticatedHandler, (req, res) => { app.get("/order_success/:trackingnumber", authenticatedHandler, (req, res) => {
let dict = { let dict = {
title: "Bestellung erfolgreich", title: "Bestellung erfolgreich",
trackingnumber: req.params.trackingnumber trackingnumber: req.params.trackingnumber
} }
res.render('order_success', dict) res.render('order_success', dict);
}) });
// Order POST Request
app.post("/order", authenticatedHandler, (req, res) => { app.post("/order", authenticatedHandler, (req, res) => {
let productId = req.body.productId; let productId = req.body.productId;
let quantity = req.body.quantity; let quantity = req.body.quantity;
@@ -179,51 +176,56 @@ app.post("/order", authenticatedHandler, (req, res) => {
result = JSON.parse(JSON.stringify(result))[0]; result = JSON.parse(JSON.stringify(result))[0];
if(quantity > result.quantity){ if(quantity > result.quantity){
res.redirect(`/order/${productId}/${quantity}/`) res.redirect(`/order/${productId}/${quantity}/`);
}else{ }else{
order_trackingnumber = uuid.v4() order_trackingnumber = uuid.v4();
mysql_handler.createOrder(userId, order_trackingnumber, 0, productId, quantity) mysql_handler.createOrder(userId, order_trackingnumber, 0, productId, quantity) ;
res.redirect("/order_success/" + order_trackingnumber) res.redirect("/order_success/" + order_trackingnumber);
} }
}); });
}) });
// Admin // Admin
app.get("/admin/product/delete/:productId", authenticatedHandler, (req, res) => { app.get("/admin/product/delete/:productId", authenticatedHandler, (req, res) => {
if(req.isAdmin){ if(req.isAdmin){
productId = req.params.productId productId = req.params.productId;
mysql_handler.con.query(`DELETE FROM products WHERE id=${productId}`, function(err, result){ mysql_handler.con.query(`DELETE FROM products WHERE id=${productId}`, function(err, result){
if(err) console.log(err); if(err) console.log(err);
}); });
} }
}) });
// AUTH // Authentication
// Logout
app.get("/logout/", authenticatedHandler, (req, res) => { app.get("/logout/", authenticatedHandler, (req, res) => {
res.clearCookie("authcookie") res.clearCookie("authcookie"); // Clear cookie
res.redirect("/") res.redirect("/");
}) });
// Register Page
app.get("/register/:error?", notAuthenticatedHandler, (req, res) => { app.get("/register/:error?", notAuthenticatedHandler, (req, res) => {
let dict = { let dict = {
title: "Register", title: "Register",
error: req.params.error error: req.params.error
} }
res.render('register', dict) res.render('register', dict);
}) });
// Login Page
app.get("/login/:error?", notAuthenticatedHandler, (req, res) => { app.get("/login/:error?", notAuthenticatedHandler, (req, res) => {
let dict = { let dict = {
title: "Login", title: "Login",
error: req.params.error error: req.params.error
} }
res.render('login', dict) res.render('login', dict);
}) });
// Register POST Request
app.post("/auth/register", notAuthenticatedHandler,(req, res) =>{ app.post("/auth/register", notAuthenticatedHandler,(req, res) =>{
// Get data from POST request
let username = req.body.username; let username = req.body.username;
let email = req.body.email; let email = req.body.email;
let password1 = req.body.password1; let password1 = req.body.password1;
@@ -237,51 +239,52 @@ app.post("/auth/register", notAuthenticatedHandler,(req, res) =>{
let cityName = req.body.cityName; let cityName = req.body.cityName;
let country = req.body.country; let country = req.body.country;
error = "" let error = ""; // Error message
if(password1 != password2){ if(password1 != password2){ // If passwords don't match
error += "Passwörter sind unterschiedlich!"; error += "Passwörter sind unterschiedlich!";
}else if(password1.length < 8){ }else if(password1.length < 8){ // If password is too short
error += "Passwort muss mindestens 8 Zeichen lang sein!" error += "Passwort muss mindestens 8 Zeichen lang sein!";
} }
if(username.length < 3){ if(username.length < 3){ // If username is too short
error += "<br> Der Benutzername muss mindestens 3 Zeichen lang sein!"; error += "<br> Der Benutzername muss mindestens 3 Zeichen lang sein!";
}else if(username.length > 30){ }else if(username.length > 30){ // If username is too long
error += "<br> Der Benutzername darf maximal 30 Zeichen lang sein!"; error += "<br> Der Benutzername darf maximal 30 Zeichen lang sein!";
} }
if(error != ""){ if(error != ""){ // If there is an error
res.redirect(`/register/${error}`) res.redirect(`/register/${error}`); // Redirect to register page with error message
}else{ }else{
bcrypt.genSalt(10, function(err, salt) { bcrypt.genSalt(10, function(err, salt) { // Generate salt
bcrypt.hash(password1, salt, function(err, hash){ bcrypt.hash(password1, salt, function(err, hash){ // Hash password
mysql_handler.createUser(username, email, hash, firstname, lastname, gender, street, housenumber, postcode, cityName, country); mysql_handler.createUser(username, email, hash, firstname, lastname, gender, street, housenumber, postcode, cityName, country);
res.redirect(`/login/`);
res.redirect(`/login/`) });
}) });
})
} }
}) });
// Login POST Request
app.post("/auth/login", notAuthenticatedHandler, (req, res) =>{ app.post("/auth/login", notAuthenticatedHandler, (req, res) =>{
// Get data from POST request
let username = req.body.username; let username = req.body.username;
let password = req.body.password; let password = req.body.password;
error = "" error = "" // Error message
mysql_handler.con.query(`SELECT * FROM users WHERE username = "${username}"`, function(err, result){ mysql_handler.con.query(`SELECT * FROM users WHERE username = "${username}"`, function(err, result){ // Get user from database
if(err){ if(err){ // If there is an error
error = "Login-Daten falsch!" error = "Login-Daten falsch!"
}else{ }else{ // If there is no error
if(JSON.parse(JSON.stringify(result))[0]){ result = JSON.parse(JSON.stringify(result))[0]; // Parse result from database
user = JSON.parse(JSON.stringify(result))[0] if(result){ // If there is a user
dbPassword = user.password; user = result; // Set user
dbPassword = user.password; // Get password from database
bcrypt.compare(password, dbPassword, function(err, matched){ // Compare password
bcrypt.compare(password, dbPassword, function(err, matched){
if(err) console.log(err); if(err) console.log(err);
if(matched){ if(matched){ // If password matches
// login // Set cookie
const token = jwt.sign({user:user.id}, SECRET_KEY) const token = jwt.sign({user:user.id}, SECRET_KEY)
res.cookie('authcookie', token, {maxAge: 90000000, httpOnly: true}) res.cookie('authcookie', token, {maxAge: 90000000, httpOnly: true})
res.redirect(`/`) res.redirect(`/`)
@@ -289,18 +292,16 @@ app.post("/auth/login", notAuthenticatedHandler, (req, res) =>{
error = "Login-Daten falsch!" error = "Login-Daten falsch!"
} }
}) })
}else{ }else{
error = "Login-Daten falsch!" error = "Login-Daten falsch!"
} }
} }
if(error != ""){ if(error != ""){ // If there is an error
res.redirect(`/login/${error}`) res.redirect(`/login/${error}`)
} }
}); });
}) })
app.listen(port, () =>{ app.listen(port, () =>{ // Start server
console.log("Listining to " + port) console.log("Listining to " + port)
}) })

View File

@@ -1,5 +1,4 @@
let mysql = require('mysql') const mysql = require('mysql')
let connected = false;
// TODO check here for errors and do not let the db throw an error in order to give the user feedback // TODO check here for errors and do not let the db throw an error in order to give the user feedback
@@ -9,114 +8,107 @@ con.query("SELECT * FROM users", function(err, result){
} }
console.log(result); console.log(result);
}); });
*/ */
let con = mysql.createConnection({
let con = mysql.createConnection({ // TODO: change to config file
host: "localhost", host: "localhost",
user: "onlineshop", user: "onlineshop",
password: "TestUser321", password: "TestUser321", // TODO: DO NOT STORE PASSWORDS IN THE CODE
database: "onlineshop" database: "onlineshop"
}); });
con.connect(function(err){ con.connect(function(err){ // Connect to the database
if(err) throw err; if(err) throw err;
console.log("Connected to MySQL!"); console.log("Connected to MySQL!");
connected = true
//createUser("dertyp", "address@email.com", "password", "Janis", "Meister", "Herr");
//createAddress("street", "1", "postcode", "city", "country", 18)
//createSeller("TEST", "test")
//createProduct("name", 1.2, "description", 2, 2, 1, 1)
//createReview("TESt", "Content", 6, 18, 1)
//createOrder(18, "tasddadse");
//createOrderProduct(1.5, 5, 1, 1)
}) })
function isConnected(){ function isConnected(){
if(connected){ // Check if database is connected
return true; if(con.state === 'disconnected'){
}else{
console.log("not connected to mysql")
return false; return false;
} }
return true;
} }
function sendQuery(sql){ // Create Order database structure
if(isConnected){ function createOrder(userId, trackingnumber, received, productId, quantity){ // TODO: add date
con.query(sql, function(err, result){ // create order status
if(err){ con.query(`INSERT INTO order_status(received, trackingnumber) VALUES (${received}, '${trackingnumber}')`, (err, result) => {
console.log(err);
return false;
}
return result;
});
}
}
// CREATES
function createOrder(userId, trackingnumber, received, productId, quantity){
con.query(`INSERT INTO order_status(received, trackingnumber) VALUES (${received}, '${trackingnumber}')`, function(err, result){
if(err) console.log(err); if(err) console.log(err);
con.query(`INSERT INTO orders(userId, order_statusId) // create order
VALUES ((SELECT id FROM users WHERE id='${userId}'), (SELECT id FROM order_status WHERE trackingnumber='${trackingnumber}'))`, function(err, result){ con.query(`INSERT INTO orders(userId, order_statusId) VALUES ((SELECT id FROM users WHERE id='${userId}'),
(SELECT id FROM order_status WHERE trackingnumber='${trackingnumber}'))`, function(err, result){
// create order_product
con.query(`SELECT orders.id FROM orders LEFT JOIN order_status ON orders.order_statusId=order_status.id WHERE order_status.trackingnumber='${order_trackingnumber}'`, function(err, result){ con.query(`SELECT orders.id FROM orders LEFT JOIN order_status ON orders.order_statusId=order_status.id WHERE order_status.trackingnumber='${order_trackingnumber}'`, function(err, result){
if(err) console.log(err); if(err) console.log(err);
order = JSON.parse(JSON.stringify(result))[0]; order = JSON.parse(JSON.stringify(result))[0]; // parse result to json
if(order != undefined){ // if order is not undefined
con.query(`SELECT * FROM products WHERE id=${productId}`, (err, result) => { // get product
if(err) console.log(err);
con.query(`SELECT * FROM products WHERE id=${productId}`, (err, result) => { product = JSON.parse(JSON.stringify(result))[0]; // parse result to json
if(err) console.log(err);
product = JSON.parse(JSON.stringify(result))[0]; // update old product quantity
con.query(`UPDATE products SET quantity=quantity-${quantity} WHERE id=${productId}`, (err, result) => {
con.query(`UPDATE products SET quantity=quantity-${quantity} WHERE id=${productId}`, (err, result) => { // create order_product
con.query(`INSERT INTO order_products(price, quantity, productId, orderId) con.query(`INSERT INTO order_products(price, quantity, productId, orderId)
VALUES ('${product.price}','${quantity}', VALUES ('${product.price}','${quantity}',
(SELECT id FROM products WHERE id='${product.id}'), (SELECT id FROM orders WHERE id='${order.id}'))`, (err, result) => { (SELECT id FROM products WHERE id='${product.id}'), (SELECT id FROM orders WHERE id='${order.id}'))`, (err, result) => {
if(err) console.log(err); if(err) console.log(err);
}) });
}) });
}) });
}) }
});
}) });
});
})
} }
function createReview(title, content, rating, userID, productId){ // Create Review
sendQuery(`INSERT INTO reviews(title, content, rating, userID, productId) function createReview(title, content, rating, userID, productId){ // TODO: add date
con.query(`INSERT INTO reviews(title, content, rating, userID, productId)
VALUES ('${title}','${content}','${rating}', VALUES ('${title}','${content}','${rating}',
(SELECT id FROM users WHERE id='${userID}'), (SELECT id FROM products WHERE id='${productId}'))`); (SELECT id FROM users WHERE id='${userID}'), (SELECT id FROM products WHERE id='${productId}'))`, (err, result) => {
if(err) console.log(err);
});
} }
// Create Product
function createProduct(name, price, description, quantity, delivery_time, sellerId, categoryId){ function createProduct(name, price, description, quantity, delivery_time, sellerId, categoryId){
sendQuery(`INSERT INTO products(name, price, description, quantity, delivery_time, sellerId, categoryId) con.query(`INSERT INTO products(name, price, description, quantity, delivery_time, sellerId, categoryId)
VALUES ('${name}',${price},'${description}','${quantity}','${delivery_time}', VALUES ('${name}',${price},'${description}','${quantity}','${delivery_time}',
(SELECT id FROM sellers WHERE id='${sellerId}'), (SELECT id FROM categories WHERE id='${categoryId}'))`); (SELECT id FROM sellers WHERE id='${sellerId}'), (SELECT id FROM categories WHERE id='${categoryId}'))`, (err, result) => {
if(err) console.log(err);
});
} }
function createCategory(name){ // Create User database structure
sendQuery(`INSERT INTO categories(name) VALUES ('${name}')`); function createUser(username, email, password, firstname, lastname, gender, street, housenumber, postcode, cityName, country){ // TODO: Better error handling if something goes wrong in progress
} // Create User
con.query(`INSERT INTO users(username, email, password) VALUES ('${username}','${email}','${password}')`, (err, result) =>{
function createSeller(name, description){
sendQuery(`INSERT INTO sellers(name, description) VALUES ('${name}', '${description}')`);
}
function createUser(username, email, password, firstname, lastname, gender, street, housenumber, postcode, cityName, country){
con.query(`INSERT INTO users(username, email, password) VALUES ('${username}','${email}','${password}')`, function(err, result){
if(err){ if(err){
console.log(err); console.log(err);
}else if(result){ }else if(result){
sendQuery(`INSERT INTO userinfos(firstname, lastname, gender, userId) VALUES ('${firstname}','${lastname}','${gender}', // Create User Info
(SELECT id FROM users WHERE username='${username}' AND email='${email}'))`); con.query(`INSERT INTO userinfos(firstname, lastname, gender, userId) VALUES ('${firstname}','${lastname}','${gender}',
console.log(`User created: ${username}!`) (SELECT id FROM users WHERE username='${username}' AND email='${email}'))`, (err, result) => {
if(err) console.log(err);
sendQuery(`INSERT INTO cities(name, postcode) VALUES ('${cityName}', '${postcode}')`); });
sendQuery(`INSERT INTO addresses(street, housenumber, country, userId, cityId) VALUES ('${street}','${housenumber}','${country}', // Create City
(SELECT id FROM users WHERE username='${username}'), (SELECT id FROM cities WHERE name='${cityName}' AND postcode='${postcode}'))`); con.query(`INSERT INTO cities(name, postcode) VALUES ('${cityName}', '${postcode}')`, (err, result) => {
if(err) console.log(err);
});
// Create Address
con.query(`INSERT INTO addresses(street, housenumber, country, userId, cityId) VALUES ('${street}','${housenumber}','${country}',
(SELECT id FROM users WHERE username='${username}'), (SELECT id FROM cities WHERE name='${cityName}' AND postcode='${postcode}'))`, (err, result) => {
if(err) console.log(err);
});
console.log(`User created: ${username}!`);
} }
}); });
} }
@@ -124,6 +116,6 @@ function createUser(username, email, password, firstname, lastname, gender, stre
module.exports = { module.exports = {
sendQuery, createOrder, createReview, createOrder, createReview, isConnected,
createProduct, createCategory, createSeller, createUser, con createProduct, createUser, con
} }