From 002cf7113708bd121f5973d25b8f0cedc27cb723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Rynning-T=C3=B8nnesen?= Date: Fri, 17 Jan 2020 15:59:21 +0100 Subject: [PATCH] Router thingies! --- api/login.js | 52 +++++++++++++++++ api/retrieve.js | 99 +++++++++++++++++++++++++++++++++ api/update.js | 94 +++++++++++++++++++++++++++++++ package-lock.json | 45 +++++++++++++++ package.json | 2 + index.html => public/index.html | 0 schemas/Highscore.js | 4 +- schemas/Purchase.js | 10 +++- schemas/Wine.js | 5 +- server.js | 51 +++++++++++++++-- 10 files changed, 352 insertions(+), 10 deletions(-) create mode 100644 api/login.js create mode 100644 api/retrieve.js create mode 100644 api/update.js rename index.html => public/index.html (100%) diff --git a/api/login.js b/api/login.js new file mode 100644 index 0000000..ede21d7 --- /dev/null +++ b/api/login.js @@ -0,0 +1,52 @@ +const passport = require("passport"); +const path = require("path"); +const User = require(path.join(__dirname + "/../schemas/User")); +const router = require("express").Router(); + +router.get("/", function(req, res) { + res.render("index", { user: req.user }); +}); + +router.get("/register", function(req, res) { + res.render("register", {}); +}); + +router.post("/register", function(req, res, next) { + console.log("registering user"); + User.register( + new User({ username: req.body.username }), + req.body.password, + function(err) { + if (err) { + console.log("error while user register!", err); + return next(err); + } + + console.log("user registered!"); + + res.redirect("/"); + } + ); +}); + +router.get("/login", function(req, res) { + res.render("login", { user: req.user, message: req.flash("error") }); +}); + +router.post( + "/login", + passport.authenticate("local", { + failureRedirect: "/login", + failureFlash: true + }), + function(req, res) { + res.redirect("/"); + } +); + +router.get("/logout", function(req, res) { + req.logout(); + res.redirect("/"); +}); + +module.exports = router; diff --git a/api/retrieve.js b/api/retrieve.js new file mode 100644 index 0000000..e779509 --- /dev/null +++ b/api/retrieve.js @@ -0,0 +1,99 @@ +const express = require("express"); +const path = require("path"); +const router = express.Router(); +const mongoose = require("mongoose"); +mongoose.connect("mongodb://localhost:27017/vinlottis", { + useNewUrlParser: true +}); + +const Purchase = require(path.join(__dirname + "/../schemas/Purchase")); +const Wine = require(path.join(__dirname + "/../schemas/Wine")); +const Highscore = require(path.join(__dirname + "/../schemas/Highscore")); + +router.use((req, res, next) => { + next(); +}); + +router.route("/purchase/statistics").get(async (req, res) => { + let purchases = await Purchase.find() + .populate("wines") + .sort({ date: 1 }); + res.json(purchases); +}); + +router.route("/purchase/statistics/color").get(async (req, res) => { + const countColor = await Purchase.find(); + let red = 0; + let blue = 0; + let yellow = 0; + let green = 0; + for (let i = 0; i < countColor.length; i++) { + let element = countColor[i]; + red += element.red; + blue += element.blue; + yellow += element.yellow; + green += element.green; + } + + const highscore = await Highscore.find(); + let redWin = 0; + let blueWin = 0; + let yellowWin = 0; + let greenWin = 0; + for (let i = 0; i < highscore.length; i++) { + let element = highscore[i]; + for (let y = 0; y < element.wins.length; y++) { + let currentWin = element.wins[y]; + switch (currentWin.color) { + case "blue": + blueWin += 1; + break; + case "red": + redWin += 1; + break; + case "yellow": + yellowWin += 1; + break; + case "green": + greenWin += 1; + break; + } + } + } + + const total = red + yellow + blue + green; + + res.json({ + red: { + total: red, + win: redWin + }, + blue: { + total: blue, + win: blueWin + }, + green: { + total: green, + win: greenWin + }, + yellow: { + total: yellow, + win: yellowWin + }, + total: total + }); +}); + +router.route("/highscore/statistics").get(async (req, res) => { + const highscore = await Highscore.find().populate("wins.wine"); + + res.json(highscore); +}); + +router.route("/wines/statistics").get(async (req, res) => { + const wines = await Wine.find(); + + res.json(wines); +}); + +module.exports = router; diff --git a/api/update.js b/api/update.js new file mode 100644 index 0000000..05afda5 --- /dev/null +++ b/api/update.js @@ -0,0 +1,94 @@ +const express = require("express"); +const path = require("path"); +const router = express.Router(); +const mongoose = require("mongoose"); +mongoose.connect("mongodb://localhost:27017/vinlottis", { + useNewUrlParser: true +}); + +const Purchase = require(path.join(__dirname + "/../schemas/Purchase")); +const Wine = require(path.join(__dirname + "/../schemas/Wine")); +const Highscore = require(path.join(__dirname + "/../schemas/Highscore")); + +router.use((req, res, next) => { + next(); +}); + +router.route("/log").post(async (req, res) => { + if (!req.isAuthenticated()) { + return; + } + const purchaseBody = req.body.purchase; + const winnersBody = req.body.winners; + + const date = purchaseBody.date; + const blue = purchaseBody.blue; + const red = purchaseBody.red; + const yellow = purchaseBody.yellow; + const green = purchaseBody.green; + + const winesThisDate = []; + + for (let i = 0; i < winnersBody.length; i++) { + let currentWinner = winnersBody[i]; + + let wonWine = await Wine.findOne({ name: currentWinner.wine.name }); + if (wonWine == undefined) { + const newWonWine = new Wine({ + name: currentWinner.wine.name, + vivinoLink: currentWinner.wine.vivinoLink, + rating: currentWinner.wine.rating, + occurences: 1 + }); + await newWonWine.save(); + wonWine = newWonWine; + } else { + wonWine.occurences += 1; + await wonWine.save(); + } + + winesThisDate.push(wonWine); + + const person = await Highscore.findOne({ + name: currentWinner.name + }); + + if (person == undefined) { + let newPerson = new Highscore({ + name: currentWinner.name, + wins: [ + { + color: currentWinner.color, + date: date, + wine: wonWine + } + ] + }); + + await newPerson.save(); + } else { + person.wins.push({ + color: currentWinner.color, + date: date, + wine: wonWine + }); + person.markModified("wins"); + await person.save(); + } + } + + let purchase = new Purchase({ + date: date, + blue: blue, + yellow: yellow, + red: red, + green: green, + wines: winesThisDate + }); + + await purchase.save(); + + res.send(true); +}); + +module.exports = router; diff --git a/package-lock.json b/package-lock.json index 98afb9d..a283f9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -148,6 +148,33 @@ "vary": "~1.1.2" } }, + "express-session": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.0.tgz", + "integrity": "sha512-t4oX2z7uoSqATbMfsxWMbNjAL0T5zpvcJCk3Z9wnPPN7ibddhnmDZXHfEcoBMG2ojKXZoCyPMc5FbtK+G7SoDg==", + "requires": { + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.0", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + } + } + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -337,6 +364,11 @@ "ee-first": "1.1.1" } }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -406,6 +438,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -551,6 +588,14 @@ "mime-types": "~2.1.24" } }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index f78e564..864fe67 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "author": "", "license": "ISC", "dependencies": { + "body-parser": "^1.19.0", "express": "^4.17.1", + "express-session": "^1.17.0", "mongoose": "^5.8.7", "passport": "^0.4.1", "passport-local": "^1.0.0", diff --git a/index.html b/public/index.html similarity index 100% rename from index.html rename to public/index.html diff --git a/schemas/Highscore.js b/schemas/Highscore.js index 37803e3..4b6e654 100644 --- a/schemas/Highscore.js +++ b/schemas/Highscore.js @@ -3,7 +3,7 @@ const Schema = mongoose.Schema; const Highscore = new Schema({ name: String, - Wins: [ + wins: [ { color: String, date: Date, @@ -15,4 +15,4 @@ const Highscore = new Schema({ ] }); -module.exports = Highscore; +module.exports = mongoose.model("Highscore", Highscore); diff --git a/schemas/Purchase.js b/schemas/Purchase.js index 1dcd3c1..fae2327 100644 --- a/schemas/Purchase.js +++ b/schemas/Purchase.js @@ -6,7 +6,13 @@ const Purchase = new Schema({ blue: Number, red: Number, yellow: Number, - green: Number + green: Number, + wines: [ + { + type: Schema.Types.ObjectId, + ref: "Wine" + } + ] }); -module.exports = Purchase; +module.exports = mongoose.model("Purchase", Purchase); diff --git a/schemas/Wine.js b/schemas/Wine.js index f9faf7c..ecfd113 100644 --- a/schemas/Wine.js +++ b/schemas/Wine.js @@ -4,7 +4,8 @@ const Schema = mongoose.Schema; const Wine = new Schema({ name: String, vivinoLink: String, - rating: Number + rating: Number, + occurences: Number }); -module.exports = Wine; +module.exports = mongoose.model("Wine", Wine); diff --git a/server.js b/server.js index f416557..92d2d60 100644 --- a/server.js +++ b/server.js @@ -1,9 +1,52 @@ -const express = require('express'); +const express = require("express"); const app = express(); -const path = require('path'); +const path = require("path"); +const session = require("express-session"); +const User = require(path.join(__dirname + "/schemas/User")); -app.get('/', function(req, res) { - res.sendFile(path.join(__dirname + '/index.html')); +const updateApi = require(path.join(__dirname + "/api/update")); +const retrieveApi = require(path.join(__dirname + "/api/retrieve")); +const loginApi = require(path.join(__dirname + "/api/login")); +const bodyParser = require("body-parser"); + +const mongoose = require("mongoose"); +mongoose.promise = global.Promise; +mongoose.connect("mongodb://localhost/vinlottis"); +mongoose.set("debug", true); + +app.use( + bodyParser.urlencoded({ + extended: true + }) +); +app.use(bodyParser.json()); +app.use( + session({ + secret: "passport-tutorial", + cookie: { maxAge: 60000 }, + resave: false, + saveUninitialized: false + }) +); + +const passport = require("passport"); +const LocalStrategy = require("passport-local"); + +app.use(passport.initialize()); +app.use(passport.session()); +// use static authenticate method of model in LocalStrategy +passport.use(new LocalStrategy(User.authenticate())); + +// use static serialize and deserialize of model for passport session support +passport.serializeUser(User.serializeUser()); +passport.deserializeUser(User.deserializeUser()); + +app.get("/", function(req, res) { + res.sendFile(path.join(__dirname + "/public/index.html")); }); +app.use("/", loginApi); +app.use("/api/", updateApi); +app.use("/api/", retrieveApi); + app.listen(30030);