diff --git a/api/routes/authenticate.js b/api/routes/authenticate.js index 1dfb8aa..11958cf 100644 --- a/api/routes/authenticate.js +++ b/api/routes/authenticate.js @@ -102,7 +102,7 @@ let create = (userParam) => { if (user) { // username already exists - deferred.reject('Username "' + userParam.username + '" is already taken'); + deferred.reject(new Error("Username already exists")); } else { createUser(); } diff --git a/api/routes/request.js b/api/routes/request.js index e11d641..07b0ad1 100644 --- a/api/routes/request.js +++ b/api/routes/request.js @@ -9,6 +9,10 @@ const codes = require('./http-codes'); const routerHandling = require('../middleware/router-handling'); +const apiAuthenticationMiddleware = require('../middleware/auth-middleware'); +const checkSql = require('../middleware/permission-check').checkSql; +const checkHl = require('../middleware/permission-check').checkHl; + // Mongoose Model using mongoDB const UserModel = require('../models/user'); const AwardingModel = require('../models/awarding'); @@ -31,7 +35,7 @@ const request = express.Router(); // routes ********************** request.route('/award') - .post((req, res, next) => { + .post(apiAuthenticationMiddleware, checkSql, (req, res, next) => { const award = new AwardingModel(req.body); award.confirmed = 0; award.proposer = req.user._id; @@ -54,18 +58,36 @@ request.route('/award') request.route('/promotion') - .get((req, res, next) => { + .get(apiAuthenticationMiddleware, checkSql, (req, res, next) => { const squadFilter = req.query.squadId; + const fractFilter = req.query.fractFilter; + const progressFilter = req.query.inProgress; + let filter; + if (squadFilter) { + filter = {squadId: squadFilter}; + } let userIds = []; - UserModel.find({squadId: squadFilter}, (err, items) => { + UserModel.find(filter).populate('squadId').exec((err, items) => { if (err) { err.status = codes.servererror; return next(err); } + for (let item of items) { - userIds.push(item._id); + if (!fractFilter || (fractFilter && item.squadId && item.squadId.fraction === fractFilter)) { + userIds.push(item._id); + } } - PromotionModel.find({userId: {"$in": userIds}}, {}, {sort: {timestamp: 'desc'}}).populate('userId').populate('proposer', resultSet).exec((err, items) => { + + let promotionFilter = { + userId: {"$in": userIds} + }; + if (progressFilter) { + promotionFilter.confirmed = 0; + } + + PromotionModel.find(promotionFilter, {}, {sort: {timestamp: 'desc'}}) + .populate('userId').populate('proposer', resultSet).exec((err, items) => { if (err) { err.status = codes.servererror; return next(err); @@ -83,7 +105,7 @@ request.route('/promotion') }) - .post((req, res, next) => { + .post(apiAuthenticationMiddleware, checkSql, (req, res, next) => { const promotion = new PromotionModel(req.body); promotion.confirmed = 0; promotion.proposer = req.user._id; @@ -104,6 +126,54 @@ request.route('/promotion') routerHandling.httpMethodNotAllowed ); + +request.route('/promotion/:id') + .patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => { + if (!req.body || (req.body._id && req.body._id !== req.params.id)) { + // little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match + const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id); + err.status = codes.notfound; + next(err); + return; // prevent node to process this function further after next() has finished. + } + + req.body.updatedAt = new Date(); + req.body.$inc = {__v: 1}; + + // PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing. + PromotionModel.findByIdAndUpdate(req.params.id, req.body, {new: true}, (err, item) => { + if (err) { + err.status = codes.wrongrequest; + } + else if (!item) { + err = new Error("item not found"); + err.status = codes.notfound; + } + else { + if (item.confirmed === 1) { + let updateUser = { + _id: item.userId, + rankLvl: item.newRankLvl + }; + UserModel.findByIdAndUpdate(updateUser._id, updateUser, {new: true}, (err, item) => { + if (err) { + err.status = codes.wrongrequest; + } + else if (!item) { + err = new Error("user not found"); + err.status = codes.notfound; + } + }); + } + res.locals.items = item; + } + next(err); + }) + }) + .all( + routerHandling.httpMethodNotAllowed + ); + // this middleware function can be used, if you like or remove it // it looks for object(s) in res.locals.items and if they exist, they are send to the client as json request.use(routerHandling.emptyResponse); diff --git a/api/server.js b/api/server.js index c7b375f..0645d01 100644 --- a/api/server.js +++ b/api/server.js @@ -73,7 +73,7 @@ app.use(urls.users, userRouter); app.use(urls.squads, squadRouter); app.use(urls.ranks, rankRouter); app.use(urls.decorations, decorationRouter); -app.use(urls.request, apiAuthenticationMiddleware, checkSql, requestRouter); +app.use(urls.request, requestRouter); app.use(urls.awards, awardingRouter); app.use(urls.command, apiAuthenticationMiddleware, checkAdmin, commandRouter); app.use(urls.account, apiAuthenticationMiddleware, checkAdmin, accountRouter); diff --git a/api/signature-tool/signature-tool.js b/api/signature-tool/signature-tool.js index b965556..f08ae7f 100644 --- a/api/signature-tool/signature-tool.js +++ b/api/signature-tool/signature-tool.js @@ -126,7 +126,7 @@ let addDecorationsAndSave = (userId, loadedImage, res, next) => { let ribbonPx = 598; let ribbonPy = 95; - AwardingModel.find({'userId': userId}, ['decorationId', 'date'], + AwardingModel.find({'userId': userId, 'confirmed': 1}, ['decorationId', 'date'], {sort: {date: 'asc'}}).populate('decorationId', ['isMedal']) .exec((err, awardings) => { if (err) { diff --git a/static/src/app/login/signup.component.html b/static/src/app/login/signup.component.html index b3bd14d..2d78a14 100644 --- a/static/src/app/login/signup.component.html +++ b/static/src/app/login/signup.component.html @@ -3,9 +3,11 @@
Dieses Formular nur ausfüllen wenn du einer HL angehörst oder SQL bist. Dabei den Nutzernamen aus dem OPT Forum verwenden!
- Im Forum eine Nachricht an HardiReady
- senden, in welcher der 'geheime Text' drin steht, den du bei der Registrierung nutzt.
+
Dieses Formular nur ausfüllen wenn du einer HL angehörst oder SQL bist. Dabei den Nutzernamen aus
+ dem OPT Forum verwenden!
+ Im Forum eine Nachricht an HardiReady
+ senden, in welcher der 'geheime Text' steht, den du bei der Registrierung nutzt.
Dabei kann es sich um irgend eine willkürliche Zeichenfolge oder einen Satz handeln - dient nur dem Abgleich.
Anschließend wird dein Account aktiviert und du wirst darüber per PN informiert.