From 6018bc869d4c7947ddfb722246a9ccdbc04f5405 Mon Sep 17 00:00:00 2001 From: Felix Erdmann Date: Thu, 3 Mar 2022 10:58:05 +0100 Subject: [PATCH 1/4] add route to grant badges --- .env | 4 ++++ api.js | 2 ++ package.json | 4 ++++ routes/badge/grantBadge.js | 46 ++++++++++++++++++++++++++++++++++++++ routes/badge/index.js | 10 +++++++++ 5 files changed, 66 insertions(+) create mode 100644 routes/badge/grantBadge.js create mode 100644 routes/badge/index.js diff --git a/.env b/.env index 98384d9..b2a1cc8 100644 --- a/.env +++ b/.env @@ -7,3 +7,7 @@ APP_ORIGIN=http://localhost:3000 # time in seconds SHARE_EXPIRES_IN=2592000 + +BADGES_ENDPOINT=https://api.v2.mybadges.org +BADGES_USERNAME=badges_username +BADGES_PASSWORD=badges_password diff --git a/api.js b/api.js index 749df6f..3af9e0b 100644 --- a/api.js +++ b/api.js @@ -40,6 +40,7 @@ var galleryRouter = require('./routes/gallery/index'); var projectRouter = require('./routes/project/index'); var userRouter = require('./routes/user/index'); var uploadRouter = require('./routes/upload/index'); +var badgeRouter = require('./routes/badge/index'); api.use('/tutorial', tutorialRouter); api.use('/share', shareRouter); @@ -47,6 +48,7 @@ api.use('/gallery', galleryRouter); api.use('/project', projectRouter); api.use('/user', userRouter); api.use('/upload', uploadRouter); +api.use('/badge', badgeRouter); // catch 404 and forward to error handler api.use(function(req, res, next) { diff --git a/package.json b/package.json index a444c19..cc8ff49 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "docs": "apidoc -i . -e \"docs\" \"(node_modules)\" -o docs" }, "dependencies": { + "@geobadges/badgr-api-client": "^0.12.0", "chalk": "^4.1.0", "cookie-parser": "~1.4.4", "cors": "^2.8.5", @@ -25,5 +26,8 @@ "request": "^2.88.2", "uuid": "^8.3.2", "uuidv4": "^6.2.12" + }, + "devDependencies": { + "nodemon": "^2.0.15" } } diff --git a/routes/badge/grantBadge.js b/routes/badge/grantBadge.js new file mode 100644 index 0000000..294fe33 --- /dev/null +++ b/routes/badge/grantBadge.js @@ -0,0 +1,46 @@ +// jshint esversion: 8 +// jshint node: true +"use strict"; + +const API = require("@geobadges/badgr-api-client"); + +const badgesClient = new API({ + endpoint: process.env.BADGES_ENDPOINT, + username: process.env.BADGES_USERNAME, + password: process.env.BADGES_PASSWORD, +}); + +const grantBadge = async function (req, res) { + try { + const email = req.user?.email || req.body.email; + const { badgeClassEntityId, createNotification, issuerEntityId } = req.body; + + if (!email) { + return res.status(400).send({ + message: "email missing", + }); + } + + const status = await badgesClient.grant({ + badgeClassEntityId, + createNotification, + email, + issuerEntityId, + }); + + if (!status) { + throw new Error("Could not grant badge"); + } + + res.status(200).send({ + message: "Badge granted successfully.", + }); + } catch (err) { + console.log(err); + return res.status(500).send(err); + } +}; + +module.exports = { + grantBadge, +}; diff --git a/routes/badge/index.js b/routes/badge/index.js new file mode 100644 index 0000000..560cb92 --- /dev/null +++ b/routes/badge/index.js @@ -0,0 +1,10 @@ +// jshint esversion: 8 +// jshint node: true +"use strict"; + +var express = require("express"); +var BadgeRouter = express.Router(); + +BadgeRouter.route("/grant").post(require("./grantBadge").grantBadge); + +module.exports = BadgeRouter; From d25c10b43b023e6e4994df8259398a6cf3c6fd66 Mon Sep 17 00:00:00 2001 From: Felix Erdmann Date: Thu, 3 Mar 2022 11:06:11 +0100 Subject: [PATCH 2/4] grant badge api description --- routes/badge/grantBadge.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/routes/badge/grantBadge.js b/routes/badge/grantBadge.js index 294fe33..845ec4d 100644 --- a/routes/badge/grantBadge.js +++ b/routes/badge/grantBadge.js @@ -10,10 +10,23 @@ const badgesClient = new API({ password: process.env.BADGES_PASSWORD, }); -const grantBadge = async function (req, res) { +/** + * @api {post} /grant Grant a badge + * @apiName grandBadge + * @apiDescription Grant a badge to a user. + * @apiGroup Badge + * + * @apiParam {String} email Users Email + * @apiParam {String} badgeClassEntityId ID of the badge class + * @apiParam {ObjectId} createNotification User receives an email notification + * @apiParam {ObjectId} issuerEntityId ID of the issuer + * + * @apiSuccess (Success 200) {String} message `Badge granted successfully.` + * @apiError (On error) {Obejct} 500 Complications when granting badge + */ +const grantBadge = async (req, res) => { try { - const email = req.user?.email || req.body.email; - const { badgeClassEntityId, createNotification, issuerEntityId } = req.body; + const { email, badgeClassEntityId, createNotification, issuerEntityId } = req.body; if (!email) { return res.status(400).send({ From 593050a5383363b68b504b7d29af4dd8c15435ac Mon Sep 17 00:00:00 2001 From: Mario Pesch Date: Thu, 3 Mar 2022 12:01:52 +0100 Subject: [PATCH 3/4] add badgeId and issuerId to model --- models/tutorial.js | 8 ++++++++ routes/tutorial/postTutorial.js | 2 ++ routes/tutorial/putTutorial.js | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/models/tutorial.js b/models/tutorial.js index 5c9a20d..a984a48 100644 --- a/models/tutorial.js +++ b/models/tutorial.js @@ -43,6 +43,14 @@ const TutorialSchema = new mongoose.Schema( type: String, required: true, }, + badgeId: { + type: String, + required: false, + }, + issuerId: { + type: String, + required: false, + }, steps: [ { type: StepSchema, diff --git a/routes/tutorial/postTutorial.js b/routes/tutorial/postTutorial.js index d0c7b67..01f80f4 100644 --- a/routes/tutorial/postTutorial.js +++ b/routes/tutorial/postTutorial.js @@ -66,6 +66,8 @@ const postTutorial = async function (req, res) { creator: req.user.email, title: req.body.title, steps: req.body.steps, + badgeId: req.body.badgeId, + issuerId: req.body.issuerId, }; // storing existing images in mongoDB req.files && diff --git a/routes/tutorial/putTutorial.js b/routes/tutorial/putTutorial.js index 9dc1bce..ca71ffd 100644 --- a/routes/tutorial/putTutorial.js +++ b/routes/tutorial/putTutorial.js @@ -9,6 +9,7 @@ const path = require("path"); const Tutorial = require("../../models/tutorial"); const User = require("../../models/user"); +const { update } = require("../../models/tutorial"); /** * @api {put} /tutorial/:tutorialId Update tutorial @@ -67,7 +68,10 @@ const putTutorial = async function (req, res) { if (owner === oldTutorial.creator) { var updatedTutorial = {}; updatedTutorial.title = req.body.title || oldTutorial.title; + updatedTutorial.badgeId = req.body.badgeId || oldTutorial.badgeId; + updatedTutorial.issuerId = req.body.issuerId || oldTutorial.issuerId; updatedTutorial.steps = req.body.steps || oldTutorial.steps; + // ensure that the requirement is not related to the tutorial itself if (updatedTutorial.steps[0].requirements) { updatedTutorial.steps[0].requirements = From c6e5b9f2ca74f4634283e1636d6be8d4b96fcc3c Mon Sep 17 00:00:00 2001 From: Felix Erdmann Date: Thu, 3 Mar 2022 12:05:21 +0100 Subject: [PATCH 4/4] update api param type --- routes/badge/grantBadge.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/badge/grantBadge.js b/routes/badge/grantBadge.js index 845ec4d..6b52ef6 100644 --- a/routes/badge/grantBadge.js +++ b/routes/badge/grantBadge.js @@ -18,8 +18,8 @@ const badgesClient = new API({ * * @apiParam {String} email Users Email * @apiParam {String} badgeClassEntityId ID of the badge class - * @apiParam {ObjectId} createNotification User receives an email notification - * @apiParam {ObjectId} issuerEntityId ID of the issuer + * @apiParam {boolean} createNotification User receives an email notification + * @apiParam {String} issuerEntityId ID of the issuer * * @apiSuccess (Success 200) {String} message `Badge granted successfully.` * @apiError (On error) {Obejct} 500 Complications when granting badge