This commit is contained in:
j.mei7
2022-03-26 13:54:51 +01:00
parent bfe995158e
commit 1f38925581
11 changed files with 389 additions and 76 deletions

123
index.js
View File

@@ -5,6 +5,7 @@ const cookieParser = require("cookie-parser")
const jwt = require("jsonwebtoken")
const bodyParser = require("body-parser")
const app = express()
const uuid = require("uuid");
const port = 3000
const SECRET_KEY = "KEY"
@@ -15,6 +16,7 @@ app.use(express.urlencoded({ extended: true}));
app.use(cookieParser());
app.use(bodyParser.json())
app.use(express.static(__dirname + "/static"));
/*
const authcookie = req.cookies.authcookie;
@@ -31,7 +33,7 @@ jwt.verify(authcookie, SECRET_KEY, (err, data) =>{
})
*/
function authenticateHandler(req, res, next){
function authenticatedHandler(req, res, next){
const authcookie = req.cookies.authcookie;
jwt.verify(authcookie, SECRET_KEY, (err, data) =>{
@@ -55,7 +57,21 @@ function authenticateHandler(req, res, next){
})
}
app.get("/", authenticateHandler, (req, res) => {
function notAuthenticatedHandler(req, res, next){
const authcookie = req.cookies.authcookie;
jwt.verify(authcookie, SECRET_KEY, (err, data) =>{
if(err){
console.log(err)
next();
} else if(data.user){
res.redirect("/")
}
})
}
app.get("/", authenticatedHandler, (req, res) => {
let dict = {
title: "Hallo",
isAdmin: req.isAdmin
@@ -121,8 +137,61 @@ app.get("/search", (req, res) => {
res.render('search', dict)
});
})
// Order
app.get("/order/:productId/:quantity/", authenticatedHandler, (req, res) => {
let error = ""
mysql_handler.con.query(`SELECT * FROM products WHERE id=${req.params.productId}`, function(err, result){
if(err) throw err;
result = JSON.parse(JSON.stringify(result))[0];
if(req.params.quantity > result.quantity){
error = "Nicht genug Produkte vorhanden"
}
let dict = {
title: "Bestellung",
error: error,
product: result,
quantity: req.params.quantity
}
res.render('order', dict)
});
})
app.get("/order_success/:trackingnumber", authenticatedHandler, (req, res) => {
let dict = {
title: "Bestellung erfolgreich",
trackingnumber: req.params.trackingnumber
}
res.render('order_success', dict)
})
app.post("/order", authenticatedHandler, (req, res) => {
let productId = req.body.productId;
let quantity = req.body.quantity;
let userId = req.user;
mysql_handler.con.query(`SELECT * FROM products WHERE id=${productId}`, function(err, result){
if(err) throw err;
result = JSON.parse(JSON.stringify(result))[0];
if(quantity > result.quantity){
res.redirect(`/order/${productId}/${quantity}/`)
}else{
order_trackingnumber = uuid.v4()
mysql_handler.createOrder(userId, order_trackingnumber, 0, productId, quantity)
res.redirect("/order_success/" + order_trackingnumber)
}
});
})
// Admin
app.get("/admin/product/delete/:productId", authenticateHandler, (req, res) => {
app.get("/admin/product/delete/:productId", authenticatedHandler, (req, res) => {
if(req.isAdmin){
productId = req.params.productId
mysql_handler.con.query(`DELETE FROM products WHERE id=${productId}`, function(err, result){
@@ -131,30 +200,13 @@ app.get("/admin/product/delete/:productId", authenticateHandler, (req, res) => {
}
})
// AUTH
app.get("/logout/", authenticateHandler, (req, res) => {
app.get("/logout/", authenticatedHandler, (req, res) => {
res.clearCookie("authcookie")
res.end()
res.redirect("/")
})
app.get("/register/", (req, res) => {
let dict = {
title: "Register",
error: ""
}
res.render('register', dict)
})
app.get("/login/", (req, res) => {
let dict = {
title: "Login",
error: ""
}
res.render('login', dict)
})
app.get("/register/:error", (req, res) => {
app.get("/register/:error?", notAuthenticatedHandler, (req, res) => {
let dict = {
title: "Register",
error: req.params.error
@@ -162,7 +214,7 @@ app.get("/register/:error", (req, res) => {
res.render('register', dict)
})
app.get("/login/:error", (req, res) => {
app.get("/login/:error?", notAuthenticatedHandler, (req, res) => {
let dict = {
title: "Login",
error: req.params.error
@@ -171,7 +223,7 @@ app.get("/login/:error", (req, res) => {
res.render('login', dict)
})
app.post("/auth/register", (req, res) =>{
app.post("/auth/register", notAuthenticatedHandler,(req, res) =>{
let username = req.body.username;
let email = req.body.email;
let password1 = req.body.password1;
@@ -179,6 +231,11 @@ app.post("/auth/register", (req, res) =>{
let firstname = req.body.firstname;
let lastname = req.body.lastname;
let gender = req.body.gender;
let street = req.body.street;
let housenumber = req.body.housenumber;
let postcode = req.body.postcode;
let cityName = req.body.cityName;
let country = req.body.country;
error = ""
@@ -198,14 +255,15 @@ app.post("/auth/register", (req, res) =>{
}else{
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(password1, salt, function(err, hash){
mysql_handler.createUser(username, email, hash, firstname, lastname, gender);
res.redirect(`/login/`)
mysql_handler.createUser(username, email, hash, firstname, lastname, gender, street, housenumber, postcode, cityName, country);
res.redirect(`/login/`)
})
})
}
})
app.post("/auth/login", (req, res) =>{
app.post("/auth/login", notAuthenticatedHandler, (req, res) =>{
let username = req.body.username;
let password = req.body.password;
@@ -225,7 +283,7 @@ app.post("/auth/login", (req, res) =>{
if(matched){
// login
const token = jwt.sign({user:user.id}, SECRET_KEY)
res.cookie('authcookie', token, {maxAge: 900000, httpOnly: true})
res.cookie('authcookie', token, {maxAge: 90000000, httpOnly: true})
res.redirect(`/`)
}else{
error = "Login-Daten falsch!"
@@ -237,11 +295,10 @@ app.post("/auth/login", (req, res) =>{
error = "Login-Daten falsch!"
}
}
if(error != ""){
res.redirect(`/login/${error}`)
}
});
if(error != ""){
res.redirect(`/login/${error}`)
}
})
app.listen(port, () =>{

View File

@@ -53,21 +53,34 @@ function sendQuery(sql){
}
// CREATES
function createOrder(userId, trackingnumber, received = 0){
createOrderStatus(trackingnumber);
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);
sendQuery(`INSERT INTO orders(userId, order_statusId)
VALUES ((SELECT id FROM users WHERE id='${userId}'), (SELECT id FROM order_status WHERE trackingnumber='${trackingnumber}'))`);
}
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){
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);
order = JSON.parse(JSON.stringify(result))[0];
function createOrderProduct(price, quantity, productId, orderId){
r = sendQuery(`INSERT INTO order_products(price, quantity, productId, orderId)
VALUES ('${price}','${quantity}',
(SELECT id FROM products WHERE id='${productId}'), (SELECT id FROM orders WHERE id='${orderId}'))`);
}
con.query(`SELECT * FROM products WHERE id=${productId}`, (err, result) => {
if(err) console.log(err);
product = JSON.parse(JSON.stringify(result))[0];
con.query(`UPDATE products SET quantity=quantity-${quantity} WHERE id=${productId}`, (err, result) => {
con.query(`INSERT INTO order_products(price, quantity, productId, orderId)
VALUES ('${product.price}','${quantity}',
(SELECT id FROM products WHERE id='${product.id}'), (SELECT id FROM orders WHERE id='${order.id}'))`, (err, result) => {
if(err) console.log(err);
})
})
})
})
function createOrderStatus(trackingnumber, received = 0){
sendQuery(`INSERT INTO order_status(received, trackingnumber) VALUES (${received}, '${trackingnumber}')`);
})
})
}
function createReview(title, content, rating, userID, productId){
@@ -91,23 +104,26 @@ function createSeller(name, description){
sendQuery(`INSERT INTO sellers(name, description) VALUES ('${name}', '${description}')`);
}
function createUser(username, email, password, firstname, lastname, gender){
result = sendQuery(`INSERT INTO users(username, email, password) VALUES ('${username}','${email}','${password}')`);
if(result){
sendQuery(`INSERT INTO userinfos(firstname, lastname, gender, userId) VALUES ('${firstname}','${lastname}','${gender}',
(SELECT id FROM users WHERE username='${username}' AND email='${email}'))`);
console.log(`User created: ${username}!`)
}
}
function createAddress(street, housenumber, postcode, city, country, userId){
sendQuery(`INSERT INTO addresses(street, housenumber, postcode, city, country, userId) VALUES ('${street}','${housenumber}','${postcode}','${city}','${country}',
(SELECT id FROM users WHERE id='${userId}'))`);
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){
console.log(err);
}else if(result){
sendQuery(`INSERT INTO userinfos(firstname, lastname, gender, userId) VALUES ('${firstname}','${lastname}','${gender}',
(SELECT id FROM users WHERE username='${username}' AND email='${email}'))`);
console.log(`User created: ${username}!`)
sendQuery(`INSERT INTO cities(name, postcode) VALUES ('${cityName}', '${postcode}')`);
sendQuery(`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}'))`);
}
});
}
module.exports = {
sendQuery, createOrder, createOrderProduct, createOrderStatus, createReview,
createProduct, createCategory, createSeller, createUser, createAddress, con
sendQuery, createOrder, createReview,
createProduct, createCategory, createSeller, createUser, con
}

16
package-lock.json generated
View File

@@ -15,7 +15,8 @@
"ejs": "^3.1.6",
"express": "^4.17.3",
"jsonwebtoken": "^8.5.1",
"mysql": "^2.18.1"
"mysql": "^2.18.1",
"uuid": "^8.3.2"
}
},
"node_modules/accepts": {
@@ -853,6 +854,14 @@
"node": ">= 0.4.0"
}
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -1527,6 +1536,11 @@
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",

View File

@@ -15,6 +15,7 @@
"ejs": "^3.1.6",
"express": "^4.17.3",
"jsonwebtoken": "^8.5.1",
"mysql": "^2.18.1"
"mysql": "^2.18.1",
"uuid": "^8.3.2"
}
}

View File

@@ -9,14 +9,75 @@ form{
width: 500px;
}
form input{
form label{
display:block;
margin-left: auto;
margin-right: auto;
width: 80%;
margin-top: 20px;
}
form label p{
width: 100%;
display:block;
margin-left: auto;
margin-right: auto;
margin-bottom: 0px;
font-weight: bold;
letter-spacing: 1.5px;
}
form label input{
width: 100%;
display:block;
margin-left: auto;
margin-right: auto;
height: 35px;
border-radius: 5px;
border: 2px solid rgb(0, 155, 194);
border: 2px solid rgb(0, 99, 156);
background-color: rgb(255, 255, 255);
transition: 0.1s;
transition-timing-function: linear;
outline: none !important;
}
form h4{
text-align: center;
margin-top: 30px;
margin-bottom: 0px;
}
/* Submit button with blue background horizontal center*/
form input[type="submit"]{
color: rgb(255, 255, 255);
font-weight: bold;
letter-spacing: 1.5px;
width: 100%;
display:block;
margin-top: 20px;
}
margin-left: auto;
margin-right: auto;
height: 35px;
border-radius: 5px;
border: 2px solid rgb(0, 99, 156);
background-color: rgb(0, 99, 156);
transition: 0.1s;
transition-timing-function: linear;
outline: none !important;
cursor:pointer;
}
/* Hover */
form label input:hover{
border: 2px solid rgb(1, 197, 246);
}
form label input:focus{
border: 2px solid rgb(1, 197, 246);
box-shadow: 0 0 5px #719ece62;
}
form input[type="submit"]:hover{
border: 2px solid rgb(7, 130, 200);
background-color: rgb(7, 130, 200);
}

30
static/order.css Normal file
View File

@@ -0,0 +1,30 @@
#order-info{
display: block;
margin-left: auto;
margin-right: auto;
width: 500px;
}
form input[type="submit"]{
color: rgb(255, 255, 255);
font-weight: bold;
letter-spacing: 1.5px;
width: 200px;
display:block;
margin-top: 20px;
margin-left: auto;
margin-right: auto;
height: 35px;
border-radius: 5px;
border: 2px solid rgb(0, 99, 156);
background-color: rgb(0, 99, 156);
transition: 0.1s;
transition-timing-function: linear;
outline: none !important;
cursor:pointer;
}
h3{
text-align: center;
}

View File

@@ -1,3 +1,31 @@
*{
font-family: Arial, Helvetica, sans-serif;
}
h1{
text-align: center;
}
#error-text{
color: red;
font-weight: bold;
letter-spacing: 1.5px;
margin-top: 0px;
margin-left: auto;
margin-right: auto;
width: 100%;
display:block;
text-align: center;
}
.text-redirect{
color: rgb(0, 99, 156);
font-size: 0.8em;
text-align: center;
width: 100%;
font-weight: bold;
margin-left: auto;
margin-right: auto;
display: block;
padding-top: 10px;
}

View File

@@ -8,12 +8,20 @@
<h1>Login</h1>
<form action="/auth/login" method="POST">
<p style="text-align:center;"><%- error %></p>
<p id="error-text"><%- error %></p>
<input required type="text" name="username" id="usernameInput" placeholder="Enter your username">
<input required type="password" name="password" id="passwordInput" placeholder="Enter your password">
<label for="username">
<p>Benutzername:</p>
<input required type="text" name="username" id="usernameInput" placeholder="Geben Sie Ihren Benutzernamen ein">
</label>
<label for="password">
<p>Passwort:</p>
<input required type="password" name="password" id="password1Input" placeholder="Geben Sie Ihr Passwort ein">
</label>
<input style="width: 40%;cursor:pointer;" type="submit" value="Login">
<a class="text-redirect" href="/register">Sie haben keinen Account?</a>
</form>
</body>
</html>

28
views/order.ejs Normal file
View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/head'); %>
<link rel="stylesheet" href="/order.css">
</head>
<body>
<h1>Ihre Bestellung</h1>
<p id="error-text"><%- error %></p>
<div id="order-info">
<p><b>Produktname:</b> <%= product.name %></p>
<p><b>Stückpreis:</b> <%= product.price %> €</p>
<p><b>Anzahl: </b><%= quantity %></p>
<hr>
<p><b>Gesamtpreis:</b> <%= quantity * product.price %> €</p>
</div>
<!--submit button-->
<form action="/order" method="POST">
<input type="text" name="productId" value="<%= product.id %>">
<input type="text" name="quantity" value="<%= quantity %>">
<!-- Price is calculated on backend ;) -->
<input type="submit" value="Bestellen">
</form>
</body>
</html>

12
views/order_success.ejs Normal file
View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<%- include('partials/head'); %>
<link rel="stylesheet" href="/order.css">
</head>
<body>
<h1 style="color:rgb(6, 170, 6)">Ihre Bestellung wurde in Auftrag gegeben!</h1>
<h3>Trackingnummer: <label style="color:rgb(6, 156, 170)"><%= trackingnumber %></label></h3>
<a class="text-redirect" href="/">Zurück zur Startseite</a>
</body>
</html>

View File

@@ -8,17 +8,75 @@
<h1>Register</h1>
<form action="/auth/register" method="POST">
<p style="text-align:center;"><%- error %></p>
<p id="error-text"><%- error %></p>
<input required type="text" name="username" id="usernameInput" placeholder="Enter your username">
<input required type="email" name="email" id="emailInput" placeholder="Enter your E-Mail">
<input required type="password" name="password1" id="password1Input" placeholder="Enter your password">
<input required type="password" name="password2" id="password2Input" placeholder="Repeat your password">
<input required type="text" name="firstname" id="firstnameInput" placeholder="Enter your firstname">
<input required type="text" name="lastname" id="lastnameInput" placeholder="Enter your lastname">
<input required type="text" name="gender" id="genderInput" placeholder="How should we call you?">
<h4>Account Informationen:</h4>
<input style="width: 40%;cursor:pointer;" type="submit" value="Register">
<label for="username">
<p>Benutzername:</p>
<input required type="text" name="username" id="usernameInput" placeholder="Geben Sie Ihren Benutzernamen ein">
</label>
<label for="email">
<p>E-Mail:</p>
<input required type="email" name="email" id="emailInput" placeholder="Geben Sie Ihre E-Mail-Adresse ein">
</label>
<label for="password1">
<p>Passwort:</p>
<input required type="password" name="password1" id="password1Input" placeholder="Geben Sie Ihr Passwort ein">
</label>
<label for="password2">
<p>Passwort wiederholen:</p>
<input required type="password" name="password2" id="password2Input" placeholder="wiederholen Sie Ihr Passwort">
</label>
<h4>Persönliche Informationen:</h4>
<label for="firstname">
<p>Vorname:</p>
<input required type="text" name="firstname" id="firstnameInput" placeholder="Geben Sie Ihren Vornamen ein">
</label>
<label for="lastname">
<p>Nachname:</p>
<input required type="text" name="lastname" id="lastnameInput" placeholder="Geben Sie Ihren Nachnamen ein">
</label>
<label for="gender">
<p>Anrede (z.B. Herr, Frau):</p>
<input required type="text" name="gender" id="genderInput" placeholder="Wie lautet Ihre Anrede?">
</label>
<h4>Lieferadresse:</h4>
<label for="street">
<p>Straße:</p>
<input required type="text" name="street" id="streetInput" placeholder="Geben Sie Ihre Straße ein">
</label>
<label for="housenumber">
<p>Hausnummer:</p>
<input required type="number" min="1" name="housenumber" id="housenumberInput" placeholder="Geben Sie Ihre Hausnummer ein">
</label>
<label for="postcode">
<p>Postleitzahl:</p>
<input required type="text" name="postcode" id="postcodeInput" placeholder="Geben Sie die Postleitzahl ein">
</label>
<label for="cityName">
<p>Stadt:</p>
<input required type="text" name="cityName" id="cityInput" placeholder="Geben Sie die Stadt ein">
</label>
<label for="country">
<p>Land:</p>
<input required type="text" name="country" id="countryInput" placeholder="Geben Sie das Land ein">
</label>
<input style="width: 40%;cursor:pointer;" type="submit" value="Registrieren">
<!-- Already have an account?-->
<a class="text-redirect" href="/login">Sie haben bereits einen Account?</a>
</form>
</body>
</html>