diff --git a/.drone.yml b/.drone.yml index 140bbd7..faf37c1 100644 --- a/.drone.yml +++ b/.drone.yml @@ -9,10 +9,17 @@ platform: steps: - name: frontend_install - image: node:13.6.0 + image: node:14 commands: - node -v - yarn --version +- name: backend_build + image: node:14 + commands: + - node -v + - yarn --version + - yarn + - yarn build - name: deploy image: appleboy/drone-ssh pull: true diff --git a/api/request.js b/api/request.js new file mode 100644 index 0000000..f7ac11c --- /dev/null +++ b/api/request.js @@ -0,0 +1,69 @@ +const express = require("express"); +const path = require("path"); +const RequestedWine = require(path.join( + __dirname + "/../schemas/RequestedWine" +)); +const Wine = require(path.join( + __dirname + "/../schemas/Wine" +)); + +const deleteRequestedWineById = async (req, res) => { + const { id } = req.params; + if(id == null){ + return res.json({ + message: "Id er ikke definert", + success: false + }) + } + + await RequestedWine.deleteOne({wineId: id}) + return res.json({ + message: `Slettet vin med id: ${id}`, + success: true + }); +} + +const getAllRequestedWines = async (req, res) => { + const allWines = await RequestedWine.find({}).populate("wine"); + + return res.json(allWines); +} + +const requestNewWine = async (req, res) => { + const {wine} = req.body + + let thisWineIsLOKO = await Wine.findOne({id: wine.id}) + + if(thisWineIsLOKO == undefined){ + thisWineIsLOKO = new Wine({ + name: wine.name, + vivinoLink: wine.vivinoLink, + rating: null, + occurences: null, + image: wine.image, + id: wine.id + }); + await thisWineIsLOKO.save() + } + + let requestedWine = await RequestedWine.findOne({ "wineId": wine.id}) + + if(requestedWine == undefined){ + requestedWine = new RequestedWine({ + count: 1, + wineId: wine.id, + wine: thisWineIsLOKO + }) + } else { + requestedWine.count += 1; + } + await requestedWine.save() + + return res.send(requestedWine); +} + +module.exports = { + requestNewWine, + getAllRequestedWines, + deleteRequestedWineById +}; diff --git a/api/retrieve.js b/api/retrieve.js index b6b62f4..92bb2a6 100644 --- a/api/retrieve.js +++ b/api/retrieve.js @@ -1,6 +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 diff --git a/api/router.js b/api/router.js index 880f02f..668e76a 100644 --- a/api/router.js +++ b/api/router.js @@ -3,9 +3,11 @@ const path = require("path"); // Middleware const mustBeAuthenticated = require(__dirname + "/../middleware/mustBeAuthenticated"); +const setAdminHeaderIfAuthenticated = require(__dirname + "/../middleware/setAdminHeaderIfAuthenticated"); const update = require(path.join(__dirname + "/update")); const retrieve = require(path.join(__dirname + "/retrieve")); +const request = require(path.join(__dirname + "/request")); const subscriptionApi = require(path.join(__dirname + "/subscriptions")); const loginApi = require(path.join(__dirname + "/login")); const wineinfo = require(path.join(__dirname + "/wineinfo")); @@ -18,6 +20,12 @@ const lottery = require(path.join(__dirname + "/lottery")); const router = express.Router(); +router.get("/wineinfo/search", wineinfo.wineSearch); + +router.get("/request/all", setAdminHeaderIfAuthenticated, request.getAllRequestedWines); +router.post("/request/new-wine", request.requestNewWine); +router.delete("/request/:id", request.deleteRequestedWineById); + router.get("/wineinfo/schema", mustBeAuthenticated, update.schema); router.get("/wineinfo/:ean", wineinfo.byEAN); diff --git a/api/wineinfo.js b/api/wineinfo.js index 5a8de10..e52039f 100644 --- a/api/wineinfo.js +++ b/api/wineinfo.js @@ -1,5 +1,51 @@ const fetch = require('node-fetch') const path = require('path') +const config = require(path.join(__dirname + "/../config/env/lottery.config")); + +const convertToOurWineObject = wine => { + if(wine.basic.ageLimit === "18"){ + return { + name: wine.basic.productShortName, + vivinoLink: "https://www.vinmonopolet.no/p/" + wine.basic.productId, + rating: wine.basic.alcoholContent, + occurences: 0, + id: wine.basic.productId, + image: `https://bilder.vinmonopolet.no/cache/500x500-0/${wine.basic.productId}-1.jpg`, + price: wine.prices[0].salesPrice.toString(), + country: wine.origins.origin.country + } + } +} + +const wineSearch = async (req, res) => { + const {query} = req.query + let url = new URL(`https://apis.vinmonopolet.no/products/v0/details-normal?productShortNameContains=test&maxResults=15`) + url.searchParams.set('productShortNameContains', query) + + const vinmonopoletResponse = await fetch(url, { + headers: { + "Ocp-Apim-Subscription-Key": config.vinmonopoletToken + } + }) + .then(resp => resp.json()) + .catch(err => console.error(err)) + + + if (vinmonopoletResponse.errors != null) { + return vinmonopoletResponse.errors.map(error => { + if (error.type == "UnknownProductError") { + return res.status(404).json({ + message: error.message + }) + } else { + return next() + } + }) + } + const winesConverted = vinmonopoletResponse.map(convertToOurWineObject).filter(Boolean) + + return res.send(winesConverted); +} const byEAN = async (req, res) => { const vinmonopoletResponse = await fetch("https://app.vinmonopolet.no/vmpws/v2/vmp/products/barCodeSearch/" + req.params.ean) @@ -21,5 +67,6 @@ const byEAN = async (req, res) => { }; module.exports = { - byEAN + byEAN, + wineSearch }; diff --git a/config/env/lottery.config.example.js b/config/env/lottery.config.example.js index 594b3d7..98b8d4d 100644 --- a/config/env/lottery.config.example.js +++ b/config/env/lottery.config.example.js @@ -6,5 +6,6 @@ module.exports = { date: 5, hours: 15, apiUrl: undefined, - gatewayToken: undefined -}; + gatewayToken: undefined, + vinmonopoletToken: undefined +}; \ No newline at end of file diff --git a/middleware/setAdminHeaderIfAuthenticated.js b/middleware/setAdminHeaderIfAuthenticated.js new file mode 100644 index 0000000..5f2fa03 --- /dev/null +++ b/middleware/setAdminHeaderIfAuthenticated.js @@ -0,0 +1,6 @@ +const setAdminHeaderIfAuthenticated = (req, res, next) => { + res.set("Vinlottis-Admin", req.isAuthenticated()); + return next(); +}; + +module.exports = setAdminHeaderIfAuthenticated; diff --git a/package.json b/package.json index 81d6102..a185b77 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node server.js", - "dev": "cross-env NODE_ENV=development webpack-dev-server --progress", + "dev": "cross-env NODE_ENV=development webpack-dev-server", "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" }, "author": "", diff --git a/schemas/RequestedWine.js b/schemas/RequestedWine.js new file mode 100644 index 0000000..12c7257 --- /dev/null +++ b/schemas/RequestedWine.js @@ -0,0 +1,13 @@ +const mongoose = require("mongoose"); +const Schema = mongoose.Schema; + +const RequestedWine = new Schema({ + count: Number, + wineId: String, + wine: { + type: Schema.Types.ObjectId, + ref: "Wine" + } +}); + +module.exports = mongoose.model("RequestedWine", RequestedWine); diff --git a/server.js b/server.js index 5cfb6a1..c26c7b8 100644 --- a/server.js +++ b/server.js @@ -9,7 +9,6 @@ const User = require(path.join(__dirname + "/schemas/User")); 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")); const subscriptionApi = require(path.join(__dirname + "/api/subscriptions")); //This is required for the chat to work diff --git a/src/Vinlottis.vue b/src/Vinlottis.vue index 00a0c4f..8ca8e22 100644 --- a/src/Vinlottis.vue +++ b/src/Vinlottis.vue @@ -1,6 +1,6 @@