From 262efa03807bc69b398855964d74551ee8291a4a Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 27 Aug 2020 00:27:39 +0200 Subject: [PATCH 01/23] All api endpoints are moved to apiRouter. --- server.js | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/server.js b/server.js index e0fef6f..2bbb639 100644 --- a/server.js +++ b/server.js @@ -6,16 +6,11 @@ const path = require("path"); const session = require("express-session"); const User = require(path.join(__dirname + "/schemas/User")); -const updateApi = require(path.join(__dirname + "/api/update")); -const retrieveApi = require(path.join(__dirname + "/api/retrieve")); -const subscriptionApi = require(path.join(__dirname + "/api/subscriptions")); +const apiRouter = require(path.join(__dirname + "/api/app")); + const loginApi = require(path.join(__dirname + "/api/login")); -const wineinfoApi = require(path.join(__dirname + "/api/wineinfo")); const virtualApi = require(path.join(__dirname + "/api/virtualLottery")); -const virtualRegistrationApi = require(path.join( - __dirname + "/api/virtualRegistration" -)); -const lottery = require(path.join(__dirname + "/api/lottery")); +const subscriptionApi = require(path.join(__dirname + "/api/subscriptions")); //This is required for the chat to work const chat = require(path.join(__dirname + "/api/chat"))(io); @@ -91,13 +86,9 @@ passport.deserializeUser(User.deserializeUser()); app.use("/public", express.static(path.join(__dirname, "public"))); app.use("/dist", express.static(path.join(__dirname, "public/dist"))); app.use("/", loginApi); -app.use("/api/", updateApi); -app.use("/api/", retrieveApi); -app.use("/api/", wineinfoApi); app.use("/api/", chatHistory); -app.use("/api/lottery", lottery); app.use("/api/virtual/", virtualApi(io)); -app.use("/api/virtual-registration/", virtualRegistrationApi); +app.use("/api/", apiRouter); app.use("/subscription", subscriptionApi); app.get("/dagens", function(req, res) { From ec80aa8bccdd9c83cb941af358160233b70240eb Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 27 Aug 2020 00:29:01 +0200 Subject: [PATCH 02/23] All api routes & their respective functions. --- api/app.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 api/app.js diff --git a/api/app.js b/api/app.js new file mode 100644 index 0000000..6b15e65 --- /dev/null +++ b/api/app.js @@ -0,0 +1,45 @@ +const express = require("express"); +const path = require("path"); + +// Middleware +const mustBeAuthenticated = require(__dirname + "/../middleware/mustBeAuthenticated"); + +const update = require(path.join(__dirname + "/update")); +const retrieve = require(path.join(__dirname + "/retrieve")); +const subscriptionApi = require(path.join(__dirname + "/subscriptions")); +const loginApi = require(path.join(__dirname + "/login")); +const wineinfo = require(path.join(__dirname + "/wineinfo")); +const virtualApi = require(path.join(__dirname + "/virtualLottery")); +const virtualRegistrationApi = require(path.join( + __dirname + "/virtualRegistration" +)); +const lottery = require(path.join(__dirname + "/lottery")); + + +const router = express.Router(); + +router.get("/wineinfo/:ean", wineinfo.byEAN); + +router.post("/log/wines", mustBeAuthenticated, update.submitWines); +router.get("/wineinfo/schema", update.schema); +router.post("/log", mustBeAuthenticated, update.submitLottery); + +router.get("wines/prelottery", retrieve.prelotteryWines); +router.get("/purchases/statistics", retrieve.allPurchase); +router.get("/purchases/statistics/color", retrieve.purchaseByColor); +router.get("/highscore/statistics", retrieve.highscore) +router.get("/wines/statistics", retrieve.allWines); +router.get("/wines/statistics/overall", retrieve.allWinesSummary); + +router.get("/lottery/all", lottery.all); +router.get("/lottery/latest", lottery.latest); +router.get("/lottery/by-date/:date", lottery.byEpochDate); +router.get("/lottery/by-name/:name", lottery.byName); + +// router.use("/api/", updateApi); +// router.use("/api/", retrieveApi); +// router.use("/api/", wineinfoApi); +// router.use("/api/lottery", lottery); +router.use("/api/virtual-registration/", virtualRegistrationApi); + +module.exports = router; From a6a84e4b293c9b2fda4af95f1834dc0479ca0285 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Thu, 27 Aug 2020 00:31:01 +0200 Subject: [PATCH 03/23] Api files no longer return router, exports usable functions. --- api/lottery.js | 39 +++++++++++++++++++++++---------------- api/retrieve.js | 49 ++++++++++++++++++++++++++----------------------- api/update.js | 34 +++++++++++++++------------------- api/wineinfo.js | 20 +++++++------------- 4 files changed, 71 insertions(+), 71 deletions(-) diff --git a/api/lottery.js b/api/lottery.js index 9d192f3..17d8e29 100644 --- a/api/lottery.js +++ b/api/lottery.js @@ -1,21 +1,13 @@ -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 mustBeAuthenticated = require(path.join( - __dirname + '/../middleware/mustBeAuthenticated' -)); -const config = require(path.join(__dirname + '/../config/defaults/lottery')); - const Highscore = require(path.join(__dirname + '/../schemas/Highscore')); const Wine = require(path.join(__dirname + '/../schemas/Wine')); - // Utils const epochToDateString = date => new Date(parseInt(date)).toDateString(); @@ -62,7 +54,7 @@ const resolveWineReferences = listWithWines => { } // Routes -router.route('/all').get((req, res) => { +const all = (req, res) => { return Highscore.find() .then(highscore => getHighscoreByDates(highscore)) .then(groupedLotteries => groupedHighscoreToSortedList(groupedLotteries)) @@ -70,9 +62,19 @@ router.route('/all').get((req, res) => { message: "Lotteries by date!", lotteries })) -}) +} -router.route('/by-date/:date').get((req, res) => { +const latest = (req, res) => { + return Highscore.find() + .then(highscore => getHighscoreByDates(highscore)) + .then(groupedLotteries => groupedHighscoreToSortedList(groupedLotteries)) + .then(lotteries => res.send({ + message: "Latest lottery!", + lottery: lotteries.slice(-1).pop() + })) +} + +const byEpochDate = (req, res) => { const { date } = req.params; const dateString = epochToDateString(date); @@ -92,10 +94,10 @@ router.route('/by-date/:date').get((req, res) => { }) } }) -}) +} -router.route("/by-name").get((req, res) => { - const { name } = req.query; +const byName = (req, res) => { + const { name } = req.params; return Highscore.find({ name }) .then(async (highscore) => { @@ -113,6 +115,11 @@ router.route("/by-name").get((req, res) => { }) } }) -}) +} -module.exports = router; +module.exports = { + all, + latest, + byEpochDate, + byName +}; diff --git a/api/retrieve.js b/api/retrieve.js index c7577b8..b6b62f4 100644 --- a/api/retrieve.js +++ b/api/retrieve.js @@ -13,23 +13,19 @@ const PreLotteryWine = require(path.join( __dirname + "/../schemas/PreLotteryWine" )); -router.use((req, res, next) => { - next(); -}); - -router.route("/wines/prelottery").get(async (req, res) => { +const prelotteryWines = async (req, res) => { let wines = await PreLotteryWine.find(); - res.json(wines); -}); + return res.json(wines); +}; -router.route("/purchase/statistics").get(async (req, res) => { +const allPurchase = async (req, res) => { let purchases = await Purchase.find() .populate("wines") .sort({ date: 1 }); - res.json(purchases); -}); + return res.json(purchases); +}; -router.route("/purchase/statistics/color").get(async (req, res) => { +const purchaseByColor = async (req, res) => { const countColor = await Purchase.find(); let red = 0; let blue = 0; @@ -75,7 +71,7 @@ router.route("/purchase/statistics/color").get(async (req, res) => { const total = red + yellow + blue + green; - res.json({ + return res.json({ red: { total: red, win: redWin @@ -95,21 +91,21 @@ router.route("/purchase/statistics/color").get(async (req, res) => { stolen: stolen, total: total }); -}); +}; -router.route("/highscore/statistics").get(async (req, res) => { +const highscore = async (req, res) => { const highscore = await Highscore.find().populate("wins.wine"); - res.json(highscore); -}); + return res.json(highscore); +}; -router.route("/wines/statistics").get(async (req, res) => { +const allWines = async (req, res) => { const wines = await Wine.find(); - res.json(wines); -}); + return res.json(wines); +}; -router.route("/wines/statistics/overall").get(async (req, res) => { +const allWinesSummary = async (req, res) => { const highscore = await Highscore.find().populate("wins.wine"); let wines = {}; @@ -149,7 +145,14 @@ router.route("/wines/statistics/overall").get(async (req, res) => { } } - res.json(Object.values(wines)); -}); + return res.json(Object.values(wines)); +}; -module.exports = router; +module.exports = { + prelotteryWines, + allPurchase, + purchaseByColor, + highscore, + allWines, + allWinesSummary +}; diff --git a/api/update.js b/api/update.js index 5fd2c12..fe4ec17 100644 --- a/api/update.js +++ b/api/update.js @@ -1,15 +1,11 @@ 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 sub = require(path.join(__dirname + "/../api/subscriptions")); -const mustBeAuthenticated = require(path.join( - __dirname + "/../middleware/mustBeAuthenticated" -)); const _wineFunctions = require(path.join(__dirname + "/../api/wine")); const _personFunctions = require(path.join(__dirname + "/../api/person")); @@ -19,11 +15,7 @@ const PreLotteryWine = require(path.join( __dirname + "/../schemas/PreLotteryWine" )); -router.use((req, res, next) => { - next(); -}); - -router.route("/log/wines").post(mustBeAuthenticated, async (req, res) => { +const submitWines = async (req, res) => { const wines = req.body; for (let i = 0; i < wines.length; i++) { let wine = wines[i]; @@ -50,20 +42,20 @@ router.route("/log/wines").post(mustBeAuthenticated, async (req, res) => { sub.sendNotification(subscription, message); } - res.send(true); -}); + return res.send(true); +}; -router.route("/log/schema").get(mustBeAuthenticated, async (req, res) => { +const schema = async (req, res) => { let schema = { ...PreLotteryWine.schema.obj }; let nulledSchema = Object.keys(schema).reduce((accumulator, current) => { accumulator[current] = ""; - return accumulator; + return accumulator }, {}); - res.send(nulledSchema); -}); + return res.send(nulledSchema); +} -router.route("/log").post(mustBeAuthenticated, async (req, res) => { +const submitLottery = async (req, res) => { await PreLotteryWine.deleteMany(); const purchaseBody = req.body.purchase; @@ -102,7 +94,11 @@ router.route("/log").post(mustBeAuthenticated, async (req, res) => { await purchase.save(); - res.send(true); -}); + return res.send(true); +}; -module.exports = router; +module.exports = { + submitWines, + schema, + submitLottery +}; diff --git a/api/wineinfo.js b/api/wineinfo.js index 237de19..5a8de10 100644 --- a/api/wineinfo.js +++ b/api/wineinfo.js @@ -1,15 +1,7 @@ -const express = require("express"); -const path = require("path"); -const router = express.Router(); const fetch = require('node-fetch') +const path = require('path') -const mustBeAuthenticated = require(path.join(__dirname + "/../middleware/mustBeAuthenticated")) - -router.use((req, res, next) => { - next(); -}); - -router.route("/wineinfo/:ean").get(async (req, res) => { +const byEAN = async (req, res) => { const vinmonopoletResponse = await fetch("https://app.vinmonopolet.no/vmpws/v2/vmp/products/barCodeSearch/" + req.params.ean) .then(resp => resp.json()) @@ -25,7 +17,9 @@ router.route("/wineinfo/:ean").get(async (req, res) => { }) } - res.send(vinmonopoletResponse); -}); + return res.send(vinmonopoletResponse); +}; -module.exports = router; +module.exports = { + byEAN +}; From 51a7107802b263232d7b07cbceeb6af249a4bef7 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 28 Aug 2020 18:45:33 +0200 Subject: [PATCH 04/23] Endpoints defined and exported as functions. Changed all routes to functions and export them to app.js to handle the registration of route using the functions exported from this file. --- api/app.js | 11 +++++- api/virtualLottery.js | 81 +++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/api/app.js b/api/app.js index 6b15e65..41bf2b0 100644 --- a/api/app.js +++ b/api/app.js @@ -36,10 +36,19 @@ router.get("/lottery/latest", lottery.latest); router.get("/lottery/by-date/:date", lottery.byEpochDate); router.get("/lottery/by-name/:name", lottery.byName); +router.delete('/winners', mustBeAuthenticated, virtual.removeWinners); +router.delete('/attendees', mustBeAuthenticated, virtual.removeAttendees); +router.get('/winners', virtual.winners); +router.get('/winners/secure', mustBeAuthenticated, virtual.winnersSecure); +router.post('/finish', mustBeAuthenticated, virtual.finish); +router.get('/attendee/all', virtual.attendees); +router.get('/attendee/all/secure', mustBeAuthenticated, virtual.attendeesSecure); +router.post('attendee/add', mustBeAuthenticated, virtual.addAttendee); + // router.use("/api/", updateApi); // router.use("/api/", retrieveApi); // router.use("/api/", wineinfoApi); // router.use("/api/lottery", lottery); -router.use("/api/virtual-registration/", virtualRegistrationApi); +// router.use("/api/virtual-registration/", virtualRegistrationApi); module.exports = router; diff --git a/api/virtualLottery.js b/api/virtualLottery.js index 605ec76..2a655e2 100644 --- a/api/virtualLottery.js +++ b/api/virtualLottery.js @@ -22,23 +22,19 @@ const PreLotteryWine = require(path.join( const Message = require(path.join(__dirname + "/../api/message")); -router.use((req, res, next) => { - next(); -}); - -router.route("/winners").delete(mustBeAuthenticated, async (req, res) => { +const removeWinners = async (req, res) => { await VirtualWinner.deleteMany(); io.emit("refresh_data", {}); - res.json(true); -}); + return res.json(true); +}; -router.route("/attendees").delete(mustBeAuthenticated, async (req, res) => { +const deleteAttendees = req, res) => { await Attendee.deleteMany(); io.emit("refresh_data", {}); - res.json(true); -}); + return res.json(true); +}; -router.route("/winners").get(async (req, res) => { +const winners = async (req, res) => { let winners = await VirtualWinner.find(); let winnersRedacted = []; let winner; @@ -50,18 +46,18 @@ router.route("/winners").get(async (req, res) => { }); } res.json(winnersRedacted); -}); +}; -router.route("/winners/secure").get(mustBeAuthenticated, async (req, res) => { +const winnersSecure = async (req, res) => { let winners = await VirtualWinner.find(); - res.json(winners); + return res.json(winners); }); -router.route("/winner").get(mustBeAuthenticated, async (req, res) => { +const winner = async (req, res) => { let allContestants = await Attendee.find({ winner: false }); if (allContestants.length == 0) { - res.json(false); + return res.json(false); return; } let ballotColors = []; @@ -151,8 +147,8 @@ router.route("/winner").get(mustBeAuthenticated, async (req, res) => { ); await newWinnerElement.save(); - res.json(winner); -}); + return res.json(winner); +}; const genRandomString = function(length) { return crypto @@ -168,18 +164,16 @@ const sha512 = function(password, salt) { return value; }; -router.route("/finish").get(mustBeAuthenticated, async (req, res) => { +const finish = async (req, res) => { if (!config.gatewayToken) { - res.json(false); - return; + return res.json(false); } let winners = await VirtualWinner.find({ timestamp_sent: undefined }).sort({ timestamp_drawn: 1 }); if (winners.length == 0) { - res.json(false); - return; + return res.json(false); } let firstWinner = winners[0]; @@ -188,12 +182,10 @@ router.route("/finish").get(mustBeAuthenticated, async (req, res) => { let messageSent = await Message.sendMessage(firstWinner); Message.sendUpdate(winners.slice(1)); if (!messageSent) { - res.json(false); - return; + return res.json(false); } } catch (e) { - res.json(false); - return; + return res.json(false); } firstWinner.timestamp_sent = new Date().getTime(); @@ -201,11 +193,10 @@ router.route("/finish").get(mustBeAuthenticated, async (req, res) => { await firstWinner.save(); startTimeout(firstWinner.id); - res.json(true); - return; -}); + return res.json(true); +}; -router.route("/attendees").get(async (req, res) => { +const attendees = async (req, res) => { let attendees = await Attendee.find(); let attendeesRedacted = []; let attendee; @@ -220,16 +211,16 @@ router.route("/attendees").get(async (req, res) => { yellow: attendee.yellow }); } - res.json(attendeesRedacted); -}); + return res.json(attendeesRedacted); +}; -router.route("/attendees/secure").get(mustBeAuthenticated, async (req, res) => { +const attendeesSecure = async (req, res) => { let attendees = await Attendee.find(); - res.json(attendees); + return res.json(attendees); }); -router.route("/attendee").post(mustBeAuthenticated, async (req, res) => { +return addAttendee = async (req, res) => { const attendee = req.body; const { red, blue, yellow, green } = attendee; @@ -246,7 +237,7 @@ router.route("/attendee").post(mustBeAuthenticated, async (req, res) => { io.emit("new_attendee", {}); - res.send(true); + return res.send(true); }); function shuffle(array) { @@ -305,7 +296,15 @@ function startTimeout(id) { }, 600000); } -module.exports = function(_io) { - io = _io; - return router; -}; +module.exports = { + removeWinners, + deleteAttendees, + winners, + winnersSecure, + winner, + finish, + attendees, + attendeesSecure, + addAttendee +} + From fd17e11e8703b9ea96464562b881282131fff6bb Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 28 Aug 2020 18:46:35 +0200 Subject: [PATCH 05/23] Register io to all req with app.set('socketio'). --- api/virtualLottery.js | 10 ++++++---- server.js | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/api/virtualLottery.js b/api/virtualLottery.js index 2a655e2..9bde0d2 100644 --- a/api/virtualLottery.js +++ b/api/virtualLottery.js @@ -6,10 +6,7 @@ const mongoose = require("mongoose"); mongoose.connect("mongodb://localhost:27017/vinlottis", { useNewUrlParser: true }); -let io; -const mustBeAuthenticated = require(path.join( - __dirname + "/../middleware/mustBeAuthenticated" -)); + const config = require(path.join(__dirname + "/../config/defaults/lottery")); const Attendee = require(path.join(__dirname + "/../schemas/Attendee")); @@ -24,12 +21,14 @@ const Message = require(path.join(__dirname + "/../api/message")); const removeWinners = async (req, res) => { await VirtualWinner.deleteMany(); + var io = req.app.get('socketio'); io.emit("refresh_data", {}); return res.json(true); }; const deleteAttendees = req, res) => { await Attendee.deleteMany(); + var io = req.app.get('socketio'); io.emit("refresh_data", {}); return res.json(true); }; @@ -127,6 +126,7 @@ const winner = async (req, res) => { Math.floor(Math.random() * attendeeListDemocratic.length) ]; + var io = req.app.get('socketio'); io.emit("winner", { color: colorToChooseFrom, name: winner.name }); let newWinnerElement = new VirtualWinner({ @@ -235,6 +235,8 @@ return addAttendee = async (req, res) => { }); await newAttendee.save(); + + var io = req.app.get('socketio'); io.emit("new_attendee", {}); return res.send(true); diff --git a/server.js b/server.js index 2bbb639..dae5002 100644 --- a/server.js +++ b/server.js @@ -71,6 +71,8 @@ app.use( }) ); +app.set('socketio', io); + const passport = require("passport"); const LocalStrategy = require("passport-local"); From dde8fe1cbe71738b375138748c91a31193116ec1 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 6 Sep 2020 14:07:18 +0200 Subject: [PATCH 06/23] Renamed app > router.js. VirtualLottery in router. --- api/app.js | 54 -------------------------------------------- api/router.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ server.js | 3 +-- 3 files changed, 63 insertions(+), 56 deletions(-) delete mode 100644 api/app.js create mode 100644 api/router.js diff --git a/api/app.js b/api/app.js deleted file mode 100644 index 41bf2b0..0000000 --- a/api/app.js +++ /dev/null @@ -1,54 +0,0 @@ -const express = require("express"); -const path = require("path"); - -// Middleware -const mustBeAuthenticated = require(__dirname + "/../middleware/mustBeAuthenticated"); - -const update = require(path.join(__dirname + "/update")); -const retrieve = require(path.join(__dirname + "/retrieve")); -const subscriptionApi = require(path.join(__dirname + "/subscriptions")); -const loginApi = require(path.join(__dirname + "/login")); -const wineinfo = require(path.join(__dirname + "/wineinfo")); -const virtualApi = require(path.join(__dirname + "/virtualLottery")); -const virtualRegistrationApi = require(path.join( - __dirname + "/virtualRegistration" -)); -const lottery = require(path.join(__dirname + "/lottery")); - - -const router = express.Router(); - -router.get("/wineinfo/:ean", wineinfo.byEAN); - -router.post("/log/wines", mustBeAuthenticated, update.submitWines); -router.get("/wineinfo/schema", update.schema); -router.post("/log", mustBeAuthenticated, update.submitLottery); - -router.get("wines/prelottery", retrieve.prelotteryWines); -router.get("/purchases/statistics", retrieve.allPurchase); -router.get("/purchases/statistics/color", retrieve.purchaseByColor); -router.get("/highscore/statistics", retrieve.highscore) -router.get("/wines/statistics", retrieve.allWines); -router.get("/wines/statistics/overall", retrieve.allWinesSummary); - -router.get("/lottery/all", lottery.all); -router.get("/lottery/latest", lottery.latest); -router.get("/lottery/by-date/:date", lottery.byEpochDate); -router.get("/lottery/by-name/:name", lottery.byName); - -router.delete('/winners', mustBeAuthenticated, virtual.removeWinners); -router.delete('/attendees', mustBeAuthenticated, virtual.removeAttendees); -router.get('/winners', virtual.winners); -router.get('/winners/secure', mustBeAuthenticated, virtual.winnersSecure); -router.post('/finish', mustBeAuthenticated, virtual.finish); -router.get('/attendee/all', virtual.attendees); -router.get('/attendee/all/secure', mustBeAuthenticated, virtual.attendeesSecure); -router.post('attendee/add', mustBeAuthenticated, virtual.addAttendee); - -// router.use("/api/", updateApi); -// router.use("/api/", retrieveApi); -// router.use("/api/", wineinfoApi); -// router.use("/api/lottery", lottery); -// router.use("/api/virtual-registration/", virtualRegistrationApi); - -module.exports = router; diff --git a/api/router.js b/api/router.js new file mode 100644 index 0000000..880f02f --- /dev/null +++ b/api/router.js @@ -0,0 +1,62 @@ +const express = require("express"); +const path = require("path"); + +// Middleware +const mustBeAuthenticated = require(__dirname + "/../middleware/mustBeAuthenticated"); + +const update = require(path.join(__dirname + "/update")); +const retrieve = require(path.join(__dirname + "/retrieve")); +const subscriptionApi = require(path.join(__dirname + "/subscriptions")); +const loginApi = require(path.join(__dirname + "/login")); +const wineinfo = require(path.join(__dirname + "/wineinfo")); +const virtualApi = require(path.join(__dirname + "/virtualLottery")); +const virtualRegistrationApi = require(path.join( + __dirname + "/virtualRegistration" +)); +const lottery = require(path.join(__dirname + "/lottery")); + + +const router = express.Router(); + +router.get("/wineinfo/schema", mustBeAuthenticated, update.schema); +router.get("/wineinfo/:ean", wineinfo.byEAN); + +router.post("/log/wines", mustBeAuthenticated, update.submitWines); +router.post("/lottery", update.submitLottery); +router.post("/lottery/wines", update.submitWinesToLottery); +// router.delete("/lottery/wine/:id", update.deleteWineFromLottery); +router.post("/lottery/winners", update.submitWinnersToLottery); + +router.get("/wines/prelottery", retrieve.prelotteryWines); +router.get("/purchase/statistics", retrieve.allPurchase); +router.get("/purchase/statistics/color", retrieve.purchaseByColor); +router.get("/highscore/statistics", retrieve.highscore) +router.get("/wines/statistics", retrieve.allWines); +router.get("/wines/statistics/overall", retrieve.allWinesSummary); + +router.get("/lottery/all", lottery.all); +router.get("/lottery/latest", lottery.latest); +router.get("/lottery/by-date/:date", lottery.byEpochDate); +router.get("/lottery/by-name/:name", lottery.byName); + +router.delete('/virtual/winner/all', mustBeAuthenticated, virtualApi.deleteWinners); +router.delete('/virtual/attendee/all', mustBeAuthenticated, virtualApi.deleteAttendees); +router.get('/virtual/winner/draw', virtualApi.drawWinner); +router.get('/virtual/winner/all', virtualApi.winners); +router.get('/virtual/winner/all/secure', mustBeAuthenticated, virtualApi.winnersSecure); +router.post('/virtual/finish', mustBeAuthenticated, virtualApi.finish); +router.get('/virtual/attendee/all', virtualApi.attendees); +router.get('/virtual/attendee/all/secure', mustBeAuthenticated, virtualApi.attendeesSecure); +router.post('/virtual/attendee/add', mustBeAuthenticated, virtualApi.addAttendee); + +router.post('/winner/notify/:id', virtualRegistrationApi.sendNotificationToWinnerById); +router.get('/winner/:id', virtualRegistrationApi.getWinesToWinnerById); +router.post('/winner/:id', virtualRegistrationApi.registerWinnerSelection); + +// router.use("/api/", updateApi); +// router.use("/api/", retrieveApi); +// router.use("/api/", wineinfoApi); +// router.use("/api/lottery", lottery); +// router.use("/virtual-registration/", virtualRegistrationApi); + +module.exports = router; diff --git a/server.js b/server.js index dae5002..4ab7946 100644 --- a/server.js +++ b/server.js @@ -6,7 +6,7 @@ const path = require("path"); const session = require("express-session"); const User = require(path.join(__dirname + "/schemas/User")); -const apiRouter = require(path.join(__dirname + "/api/app")); +const apiRouter = require(path.join(__dirname + "/api/router.js")); const loginApi = require(path.join(__dirname + "/api/login")); const virtualApi = require(path.join(__dirname + "/api/virtualLottery")); @@ -89,7 +89,6 @@ app.use("/public", express.static(path.join(__dirname, "public"))); app.use("/dist", express.static(path.join(__dirname, "public/dist"))); app.use("/", loginApi); app.use("/api/", chatHistory); -app.use("/api/virtual/", virtualApi(io)); app.use("/api/", apiRouter); app.use("/subscription", subscriptionApi); From 4f054a0437ac4c85f865b7525dba1694b5f7d219 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 6 Sep 2020 14:09:10 +0200 Subject: [PATCH 07/23] Message uses node's https insteadof requests. Messages re-written to use nodes built in https over external requests package. Also updated message functions to always return promises and have clearer names for what their purpose is. --- api/message.js | 129 ++++++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 56 deletions(-) diff --git a/api/message.js b/api/message.js index e8a1eec..a763a7b 100644 --- a/api/message.js +++ b/api/message.js @@ -1,92 +1,109 @@ -const request = require("request"); +const https = require("https"); const path = require("path"); const config = require(path.join(__dirname + "/../config/defaults/lottery")); -async function sendMessage(winnerObject) { +async function sendWineSelectMessage(winnerObject) { winnerObject.timestamp_sent = new Date().getTime(); winnerObject.timestamp_limit = new Date().getTime() * 600000; await winnerObject.save(); let url = new URL(`/#/winner/${winnerObject.id}`, "https://lottis.vin"); - await sendMessageToUser( + return sendMessageToUser( winnerObject.phoneNumber, `Gratulerer som heldig vinner av vinlotteriet ${winnerObject.name}! Her er linken for å velge hva slags vin du vil ha, du har 10 minutter på å velge ut noe før du blir lagt bakerst i køen. ${url.href}. (Hvis den siden kommer opp som tom må du prøve å refreshe siden noen ganger.)` - ); - - return true; + ) } -async function sendWonWineMessage(winnerObject, wineObject) { - console.log( - `User ${winnerObject.id} is only one left, chosing wine for him/her.` - ); +async function sendLastWinnerMessage(winnerObject, wineObject) { + console.log(`User ${winnerObject.id} is only one left, chosing wine for him/her.`); winnerObject.timestamp_sent = new Date().getTime(); winnerObject.timestamp_limit = new Date().getTime(); await winnerObject.save(); - await sendMessageToUser( + return sendMessageToUser( winnerObject.phoneNumber, `Gratulerer som heldig vinner av vinlotteriet ${winnerObject.name}! Du har vunnet vinen ${wineObject.name}, og vil få nærmere info om hvordan/hvor du kan hente vinen snarest. Ha en ellers fin helg!` ); - - return true; } -async function sendMessageTooLate(winnerObject) { - await sendMessageToUser( +async function sendWineSelectMessageTooLate(winnerObject) { + return sendMessageToUser( winnerObject.phoneNumber, `Hei ${winnerObject.name}, du har dessverre brukt mer enn 10 minutter på å velge premie og blir derfor puttet bakerst i køen. Du vil få en ny SMS når det er din tur igjen.` ); } async function sendMessageToUser(phoneNumber, message) { - try { - request.post( - { - url: `https://gatewayapi.com/rest/mtsms?token=${config.gatewayToken}`, - json: true, - body: { - sender: "Vinlottis", - message: message, - recipients: [{ msisdn: `47${phoneNumber}` }] - } - }, - function(err, r, body) { - console.log(err ? err : body); - if(err) { - console.log(phoneNumber, message); - } - } - ); - } catch(e) { - console.log(phoneNumber, message); - } + console.log(`Attempting to send message to ${ phoneNumber }.`) + + const body = { + sender: "Vinlottis", + message: message, + recipients: [{ msisdn: `47${ phoneNumber }`}] + }; + + return gatewayRequest(body); } -async function sendUpdate(winners) { + +async function sendInitialMessageToWinners(winners) { let numbers = []; for (let i = 0; i < winners.length; i++) { numbers.push({ msisdn: `47${winners[i].phoneNumber}` }); } - request.post( - { - url: `https://gatewayapi.com/rest/mtsms?token=${config.gatewayToken}`, - json: true, - body: { - sender: "Vinlottis", - message: - "Gratulerer som vinner av vinlottisen! Du vil snart få en SMS med oppdatering om hvordan gangen går!", - recipients: numbers - } - }, - function(err, r, body) { - console.log(err ? err : body); - } - ); + + const body = { + sender: "Vinlottis", + message: + "Gratulerer som vinner av vinlottisen! Du vil snart få en SMS med oppdatering om hvordan gangen går!", + recipients: numbers + } + + return gatewayRequest(body); } -module.exports.sendUpdate = sendUpdate; -module.exports.sendMessage = sendMessage; -module.exports.sendMessageTooLate = sendMessageTooLate; -module.exports.sendWonWineMessage = sendWonWineMessage; +async function gatewayRequest(body) { + return new Promise((resolve, reject) => { + const options = { + hostname: "gatewayapi.com", + post: 443, + path: `/rest/mtsms?token=${ config.gatewayToken }`, + method: "POST", + headers: { + "Content-Type": "application/json" + } + } + + const req = https.request(options, (res) => { + console.log(`statusCode: ${ res.statusCode }`); + console.log(`statusMessage: ${ res.statusMessage }`); + + res.setEncoding('utf8'); + + if (res.statusCode == 200) { + res.on("data", (d) => resolve(JSON.parse(d))); + } else { + res.on("data", (data) => { + data = JSON.parse(data); + return reject('Gateway error: ' + data['message'] || data) + }); + } + }) + + req.on("error", (error) => { + console.error(`Error from sms service: ${ error }`); + reject(`Error from sms service: ${ error }`); + }) + + req.write(JSON.stringify(body)); + req.end(); + }); +} + +module.exports = { + sendWineSelectMessage, + sendLastWinnerMessage, + sendWineSelectMessageTooLate, + sendInitialMessageToWinners +} From 1d714d1e5a62c9437a53645af722470c58438cc8 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 6 Sep 2020 14:14:26 +0200 Subject: [PATCH 08/23] Removed router, refactored virtual functoinality. - Removed the router from virtualRegistration so router.js handles routing and virtualRegistration only exports functions. - Refactored what code is in each of the virtual(Lottery/Registration) files. /finish in Lottery now only sends update to all winners and delegates sending to next winner in line, and setting timeout to virtualRegistration. - Better error handling and all responses from virtualRegistration has message in json response. --- api/virtualLottery.js | 252 ++++++++++++++++--------------------- api/virtualRegistration.js | 175 ++++++++++++++++---------- 2 files changed, 212 insertions(+), 215 deletions(-) diff --git a/api/virtualLottery.js b/api/virtualLottery.js index 9bde0d2..81107dc 100644 --- a/api/virtualLottery.js +++ b/api/virtualLottery.js @@ -1,37 +1,14 @@ -const express = require("express"); const path = require("path"); -const router = express.Router(); const crypto = require("crypto"); -const mongoose = require("mongoose"); -mongoose.connect("mongodb://localhost:27017/vinlottis", { - useNewUrlParser: true -}); const config = require(path.join(__dirname + "/../config/defaults/lottery")); +const Message = require(path.join(__dirname + "/message")); +const { findAndNotifyNextWinner } = require(path.join(__dirname + "/virtualRegistration")); const Attendee = require(path.join(__dirname + "/../schemas/Attendee")); -const VirtualWinner = require(path.join( - __dirname + "/../schemas/VirtualWinner" -)); -const PreLotteryWine = require(path.join( - __dirname + "/../schemas/PreLotteryWine" -)); +const VirtualWinner = require(path.join(__dirname + "/../schemas/VirtualWinner")); +const PreLotteryWine = require(path.join(__dirname + "/../schemas/PreLotteryWine")); -const Message = require(path.join(__dirname + "/../api/message")); - -const removeWinners = async (req, res) => { - await VirtualWinner.deleteMany(); - var io = req.app.get('socketio'); - io.emit("refresh_data", {}); - return res.json(true); -}; - -const deleteAttendees = req, res) => { - await Attendee.deleteMany(); - var io = req.app.get('socketio'); - io.emit("refresh_data", {}); - return res.json(true); -}; const winners = async (req, res) => { let winners = await VirtualWinner.find(); @@ -51,13 +28,76 @@ const winnersSecure = async (req, res) => { let winners = await VirtualWinner.find(); return res.json(winners); -}); +}; -const winner = async (req, res) => { +const deleteWinners = async (req, res) => { + await VirtualWinner.deleteMany(); + var io = req.app.get('socketio'); + io.emit("refresh_data", {}); + return res.json(true); +}; + +const attendees = async (req, res) => { + let attendees = await Attendee.find(); + let attendeesRedacted = []; + let attendee; + for (let i = 0; i < attendees.length; i++) { + attendee = attendees[i]; + attendeesRedacted.push({ + name: attendee.name, + ballots: attendee.red + attendee.blue + attendee.yellow + attendee.green, + red: attendee.red, + blue: attendee.blue, + green: attendee.green, + yellow: attendee.yellow + }); + } + return res.json(attendeesRedacted); +}; + +const attendeesSecure = async (req, res) => { + let attendees = await Attendee.find(); + + return res.json(attendees); +}; + +const addAttendee = async (req, res) => { + const attendee = req.body; + const { red, blue, yellow, green } = attendee; + + let newAttendee = new Attendee({ + name: attendee.name, + red, + blue, + green, + yellow, + phoneNumber: attendee.phoneNumber, + winner: false + }); + await newAttendee.save(); + + + var io = req.app.get('socketio'); + io.emit("new_attendee", {}); + + return res.send(true); +}; + +const deleteAttendees = async (req, res) => { + await Attendee.deleteMany(); + var io = req.app.get('socketio'); + io.emit("refresh_data", {}); + return res.json(true); +}; + +const drawWinner = async (req, res) => { let allContestants = await Attendee.find({ winner: false }); + if (allContestants.length == 0) { - return res.json(false); - return; + return res.json({ + success: false, + message: "No attendees left that have not won." + }); } let ballotColors = []; for (let i = 0; i < allContestants.length; i++) { @@ -150,6 +190,38 @@ const winner = async (req, res) => { return res.json(winner); }; +const finish = async (req, res) => { + if (!config.gatewayToken) { + return res.json({ + message: "Missing api token for sms gateway.", + success: false + }); + } + + let winners = await VirtualWinner.find({ timestamp_sent: undefined }).sort({ + timestamp_drawn: 1 + }); + + if (winners.length == 0) { + return res.json({ + message: "No winners to draw from.", + success: false + }); + } + + Message.sendInitialMessageToWinners(winners.slice(1)); + + return findAndNotifyNextWinner() + .then(() => res.json({ + success: true, + message: "Sent wine select message to first winner and update message to rest of winners." + })) + .catch(error => res.json({ + message: error["message"] || "Unable to send message to first winner.", + success: false + })) +}; + const genRandomString = function(length) { return crypto .randomBytes(Math.ceil(length / 2)) @@ -164,84 +236,6 @@ const sha512 = function(password, salt) { return value; }; -const finish = async (req, res) => { - if (!config.gatewayToken) { - return res.json(false); - } - let winners = await VirtualWinner.find({ timestamp_sent: undefined }).sort({ - timestamp_drawn: 1 - }); - - if (winners.length == 0) { - return res.json(false); - } - - let firstWinner = winners[0]; - messageSent = false; - try { - let messageSent = await Message.sendMessage(firstWinner); - Message.sendUpdate(winners.slice(1)); - if (!messageSent) { - return res.json(false); - } - } catch (e) { - return res.json(false); - } - - firstWinner.timestamp_sent = new Date().getTime(); - firstWinner.timestamp_limit = new Date().getTime() + 600000; - - await firstWinner.save(); - startTimeout(firstWinner.id); - return res.json(true); -}; - -const attendees = async (req, res) => { - let attendees = await Attendee.find(); - let attendeesRedacted = []; - let attendee; - for (let i = 0; i < attendees.length; i++) { - attendee = attendees[i]; - attendeesRedacted.push({ - name: attendee.name, - ballots: attendee.red + attendee.blue + attendee.yellow + attendee.green, - red: attendee.red, - blue: attendee.blue, - green: attendee.green, - yellow: attendee.yellow - }); - } - return res.json(attendeesRedacted); -}; - -const attendeesSecure = async (req, res) => { - let attendees = await Attendee.find(); - - return res.json(attendees); -}); - -return addAttendee = async (req, res) => { - const attendee = req.body; - const { red, blue, yellow, green } = attendee; - - let newAttendee = new Attendee({ - name: attendee.name, - red, - blue, - green, - yellow, - phoneNumber: attendee.phoneNumber, - winner: false - }); - await newAttendee.save(); - - - var io = req.app.get('socketio'); - io.emit("new_attendee", {}); - - return res.send(true); -}); - function shuffle(array) { let currentIndex = array.length, temporaryValue, @@ -262,48 +256,12 @@ function shuffle(array) { return array; } - -function startTimeout(id) { - console.log(`Starting timeout for user ${id}.`); - setTimeout(async () => { - let virtualWinner = await VirtualWinner.findOne({ id: id }); - if (!virtualWinner) { - console.log( - `Timeout done for user ${id}, but user has already sent data.` - ); - return; - } - console.log(`Timeout done for user ${id}, sending update to user.`); - - Message.sendMessageTooLate(virtualWinner); - - virtualWinner.timestamp_drawn = new Date().getTime(); - virtualWinner.timestamp_limit = null; - virtualWinner.timestamp_sent = null; - - await virtualWinner.save(); - - let prelotteryWine = await PreLotteryWine.find(); - let nextWinner = await VirtualWinner.find().sort({ timestamp_drawn: 1 }); - if (nextWinner.length == 1 && prelotteryWine.length == 1) { - chooseForUser(nextWinner[0], prelotteryWine[0]); - } else { - nextWinner[0].timestamp_sent = new Date().getTime(); - nextWinner[0].timestamp_limit = new Date().getTime() + 600000; - await nextWinner[0].save(); - Message.sendMessage(nextWinner[0]); - startTimeout(nextWinner[0].id); - } - - }, 600000); -} - module.exports = { - removeWinners, + deleteWinners, deleteAttendees, winners, winnersSecure, - winner, + drawWinner, finish, attendees, attendeesSecure, diff --git a/api/virtualRegistration.js b/api/virtualRegistration.js index b3c128e..473d827 100644 --- a/api/virtualRegistration.js +++ b/api/virtualRegistration.js @@ -1,11 +1,4 @@ -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 _wineFunctions = require(path.join(__dirname + "/../api/wine")); const _personFunctions = require(path.join(__dirname + "/../api/person")); @@ -17,72 +10,70 @@ const PreLotteryWine = require(path.join( __dirname + "/../schemas/PreLotteryWine" )); -router.use((req, res, next) => { - next(); -}); -router.route("/winner/:id").get((req, res) => { - res.redirect(`/#/winner/${req.params.id}`); -}); - -router.route("/:id").get(async (req, res) => { +const getWinesToWinnerById = async (req, res) => { let id = req.params.id; let foundWinner = await VirtualWinner.findOne({ id: id }); if (!foundWinner) { - res.json({ + return res.json({ + success: false, + message: "No winner with this id.", existing: false, turn: false }); - return; } let allWinners = await VirtualWinner.find().sort({ timestamp_drawn: 1 }); - if ( allWinners[0].id != foundWinner.id || foundWinner.timestamp_limit == undefined || foundWinner.timestamp_sent == undefined ) { - res.json({ existing: true, turn: false }); - return; + return res.json({ + success: false, + message: "Not the winner next in line!", + existing: true, + turn: false + }); } - res.json({ + return res.json({ + success: true, existing: true, turn: true, name: foundWinner.name, color: foundWinner.color }); - return; -}); +}; -router.route("/:id").post(async (req, res) => { +const registerWinnerSelection = async (req, res) => { let id = req.params.id; let wineName = req.body.wineName; let foundWinner = await VirtualWinner.findOne({ id: id }); if (!foundWinner) { - res.json(false); - return; + return res.json({ + success: false, + message: "No winner with this id." + }) + } else if (foundWinner.timestamp_limit < new Date().getTime()) { + return res.json({ + success: false, + message: "Timelimit expired, you will receive a wine after other users have chosen.", + limit: true + }) } - if (foundWinner.timestamp_limit < new Date().getTime()) { - res.json({ - success: false, - limit: true - }); - return; - } let date = new Date(); date.setHours(5, 0, 0, 0); - let prelotteryWine = await PreLotteryWine.findOne({ name: wineName }); if (!prelotteryWine) { - res.json({ + return res.json({ success: false, - wine: true + message: "No wine with this name.", + wine: false }); } @@ -91,31 +82,78 @@ router.route("/:id").post(async (req, res) => { await _personFunctions.findSavePerson(foundWinner, wonWine, date); await foundWinner.delete(); + console.info("Saved winners choice."); - let nextWineBottle = await PreLotteryWine.find(); - let nextWinner = await VirtualWinner.find().sort({ timestamp_drawn: 1 }); - if (nextWinner.length > 1 && nextWineBottle.length > 1) { - Message.sendMessage(nextWinner[0]); - startTimeout(id); - } else if (nextWinner.length == 1 && nextWineBottle.length == 1) { - chooseForUser(nextWinner[0], nextWineBottle[0]); - } + return findAndNotifyNextWinner() + .then(() => res.json({ + message: "Choice saved and next in line notified.", + success: true + })) + .catch(error => res.json({ + message: error["message"] || "Error when notifing next winner.", + success: false + })) +}; - res.json({ - success: true - }); - return; -}); - -async function chooseForUser(winner, prelotteryWine) { +const chooseLastWineForUser = (winner, prelotteryWine) => { let date = new Date(); date.setHours(5, 0, 0, 0); - let wonWine = await _wineFunctions.findSaveWine(prelotteryWine); - await _personFunctions.findSavePerson(winner, wonWine, date); - await prelotteryWine.delete(); - await Message.sendWonWineMessage(winner, prelotteryWine); - await winner.delete(); + return _wineFunctions.findSaveWine(preLotteryWine) + .then(wonWine => _personFunctions.findSavePerson(winner, wonWine, date)) + .then(() => prelotteryWine.delete()) + .then(() => Message.sendLastWinnerMessage(winner, preLotteryWine)) + .then(() => winner.delete()); +} + +const findAndNotifyNextWinner = async () => { + let nextWinner = undefined; + + let winnersLeft = await VirtualWinner.find().sort({ timestamp_drawn: 1 }); + let winesLeft = await PreLotteryWine.find(); + + if (winnersLeft.length > 1) { + nextWinner = winnersLeft[0]; // multiple winners left, choose next in line + } else if (winnersLeft.length == 1 && winesLeft.length > 1) { + nextWinner = winnersLeft[0] // one winner left, but multiple wines + } else if (winnersLeft.length == 1 && winesLeft.length == 1) { + nextWinner = winnersLeft[0] // one winner and one wine left, choose for user + wine = winesLeft[0] + return chooseLastWineForUser(nextWinner, wine); + } + + if (nextWinner) { + return Message.sendWineSelectMessage(nextWinner) + .then(messageResponse => startTimeout(nextWinner.id)) + } else { + console.info("All winners notified. Could start cleanup here."); + return Promise.resolve({ + message: "All winners notified." + }) + } +}; + +const sendNotificationToWinnerById = async (req, res) => { + const { id } = req.params; + let winner = await VirtualWinner.findOne({ id: id }); + + if (!winner) { + return res.json({ + message: "No winner with this id.", + success: false + }) + } + + return Message.sendWineSelectMessage(winner) + .then(success => res.json({ + success: success, + message: `Message sent to winner ${id} successfully!` + })) + .catch(err => res.json({ + success: false, + message: "Error while trying to send sms.", + error: err + })) } function startTimeout(id) { @@ -123,27 +161,28 @@ function startTimeout(id) { setTimeout(async () => { let virtualWinner = await VirtualWinner.findOne({ id: id }); if (!virtualWinner) { - console.log( - `Timeout done for user ${id}, but user has already sent data.` - ); + console.log(`Timeout done for user ${id}, but user has already sent data.`); return; } console.log(`Timeout done for user ${id}, sending update to user.`); - Message.sendMessageTooLate(virtualWinner); + Message.sendWineSelectMessageTooLate(virtualWinner); virtualWinner.timestamp_drawn = new Date().getTime(); virtualWinner.timestamp_limit = null; virtualWinner.timestamp_sent = null; - await virtualWinner.save(); - let prelotteryWine = await PreLotteryWine.find(); - let nextWinner = await VirtualWinner.find().sort({ timestamp_drawn: 1 }); - if (nextWinner.length == 1 && prelotteryWine.length == 1) { - chooseForUser(nextWinner[0], prelotteryWine[0]); - } - }, 600000); + findAndNotifyNextWinner(); + }, 60000); + + return Promise.resolve() } -module.exports = router; +module.exports = { + getWinesToWinnerById, + registerWinnerSelection, + findAndNotifyNextWinner, + + sendNotificationToWinnerById +}; From a30dc2a4195e64ae76ee48887a20af3c85c9292a Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 6 Sep 2020 14:20:01 +0200 Subject: [PATCH 09/23] Renamed & moved frontend router. --- src/{routes/vinlottisRouter.js => router.js} | 0 src/vinlottis-init.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{routes/vinlottisRouter.js => router.js} (100%) diff --git a/src/routes/vinlottisRouter.js b/src/router.js similarity index 100% rename from src/routes/vinlottisRouter.js rename to src/router.js diff --git a/src/vinlottis-init.js b/src/vinlottis-init.js index 545ff89..f362976 100644 --- a/src/vinlottis-init.js +++ b/src/vinlottis-init.js @@ -1,6 +1,6 @@ import Vue from "vue"; import VueRouter from "vue-router"; -import { routes } from "@/routes/vinlottisRouter"; +import { routes } from "@/router.js"; import Vinlottis from "@/Vinlottis"; import VueAnalytics from "vue-analytics"; From 8268efe62519b456f2e42c25c8d0b30968ba1c93 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 6 Sep 2020 14:20:27 +0200 Subject: [PATCH 10/23] Include positioning stylesheet in root Vue comp. --- src/Vinlottis.vue | 1 + src/styles/positioning.scss | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 src/styles/positioning.scss diff --git a/src/Vinlottis.vue b/src/Vinlottis.vue index 23eb18e..00a0c4f 100644 --- a/src/Vinlottis.vue +++ b/src/Vinlottis.vue @@ -52,6 +52,7 @@ export default { \ No newline at end of file From 55b3552786fae2422f8c9565f61dfadf5905d7ef Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 6 Sep 2020 14:32:29 +0200 Subject: [PATCH 15/23] Flex wrap winner raffles to not overflow vertical. --- src/ui/Winners.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/Winners.vue b/src/ui/Winners.vue index f2d3764..d498eae 100644 --- a/src/ui/Winners.vue +++ b/src/ui/Winners.vue @@ -36,6 +36,7 @@ h2 { display: flex; justify-content: space-around; align-items: center; + flex-wrap: wrap; } .ballot-element { From c1f0a1b7f38a581fe8b3ca9ff661c2f5a57d7f0b Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 6 Sep 2020 14:33:45 +0200 Subject: [PATCH 16/23] Padding for air around elements. --- src/components/WinnerPage.vue | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/WinnerPage.vue b/src/components/WinnerPage.vue index 988f608..434f9d7 100644 --- a/src/components/WinnerPage.vue +++ b/src/components/WinnerPage.vue @@ -62,11 +62,9 @@ export default { this.name = winnerObject.name; const _wines = await fetch("/api/wines/prelottery"); this.wines = await _wines.json(); - console.log(this.wines); }, methods: { chosenWine: async function(name) { - console.log("chosen a wine"); let posted = await postWineChosen(this.id, name); console.log("response", posted); if (posted.success) { @@ -82,7 +80,8 @@ export default { .container { display: flex; justify-content: center; - margin-top: 4rem; + margin-top: 2rem; + padding: 2rem; } .sent-container { width: 100%; From f171853c22a02a675c0f708c60a8b08c203b4293 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 6 Sep 2020 14:34:43 +0200 Subject: [PATCH 17/23] Register wines, lottery and winners separatly. Register page now uses new /lottery, /lottery/wines and /lottery/winners endpoints for sending information separatly. This allows lottery (colors, bought total & stolen), lottery wines (prelottery wines) and lottery winners (wine mapped to winner) sent. Before /lottery/winners & /lottery was sent together to a single endpoint. --- src/components/RegisterPage.vue | 57 ++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/components/RegisterPage.vue b/src/components/RegisterPage.vue index 787ae74..933958a 100644 --- a/src/components/RegisterPage.vue +++ b/src/components/RegisterPage.vue @@ -78,6 +78,10 @@ +
+ +
+

Vinnere

Refresh data fra virtuelt lotteri
@@ -130,8 +134,8 @@
-
- +
+
@@ -142,9 +146,11 @@