Skip to content

Commit

Permalink
Merge pull request #37 from andela/ft-Manager-Declines-Request-167727465
Browse files Browse the repository at this point in the history
#167727465 Manager Can Reject User's request
  • Loading branch information
okoroemeka committed Sep 1, 2019
2 parents ffd5189 + c094e0f commit 713d169
Show file tree
Hide file tree
Showing 27 changed files with 424 additions and 88 deletions.
40 changes: 40 additions & 0 deletions src/controllers/requests.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import models from '../db/models';
import sender from '../services/email.service';

const { Request, User } = models;
/**
* This class creates the user controller
*/
export default class UserController {
/**
* @param {object} req The user's signup details
* @param {object} res The user's details returned after signup
* @returns {object} A signed up user
*/
static async rejectRequest(req, res) {
try {
const request = await Request.update(
{
status: 'declined'
}, { returning: true, where: { id: req.params.id } }
);
const requestResult = request[1][0];

const user = await User.findOne({ where: { id: requestResult.user_id } });
const { first_name: firstName, email } = user;

// parameter(s) to be passed to the sendgrid email template
await sender.sendEmail(process.env.SENDER_EMAIL, email, 'request_rejected', { firstName, email });
return res.status(201).json({
status: 'success',
data: requestResult
});
} catch (error) {
return res.status(500)
.json({
status: 'error',
error: 'Error accessing the request route',
});
}
}
}
10 changes: 5 additions & 5 deletions src/controllers/user.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ const { User } = models;
* This class creates the user controller
*/
export default class UserController {
/**
* @param {object} req The user's signup details
* @param {object} res The user's details returned after signup
* @returns {object} A signed up user
*/
/**
* @param {object} req The user's signup details
* @param {object} res The user's details returned after signup
* @returns {object} A signed up user
*/
static async signup(req, res) {
try {
const hash = await bcrypt.hash(req.body.password, 10);
Expand Down
52 changes: 0 additions & 52 deletions src/controllers/users.js

This file was deleted.

1 change: 1 addition & 0 deletions src/db/migrations/20190821142413-create-likes.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = {
}
})
),

down: (queryInterface) => queryInterface.dropTable('likes')
// the parameter "Sequelize" was removed because it is not being used
};
1 change: 1 addition & 0 deletions src/db/migrations/20190821143206-create-rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module.exports = {
}
})
),

down: (queryInterface) => queryInterface.dropTable('rooms')
// removed the parameter "Sequelize" because it is not being used
};
1 change: 1 addition & 0 deletions src/db/migrations/20190821144633-create-feedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module.exports = {
}
})
),

down: (queryInterface) => queryInterface.dropTable('feedbacks')
// removed the parameter "Sequelize" because it is not being used
};
1 change: 1 addition & 0 deletions src/db/migrations/20190821153817-create-rating.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module.exports = {
}
})
),

down: (queryInterface) => queryInterface.dropTable('ratings')
// removed the parameter "Sequelize" because it is not being used
};
1 change: 1 addition & 0 deletions src/db/migrations/20190821154724-create-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ module.exports = {
}
})
),

down: (queryInterface) => queryInterface.dropTable('requests')
// removed the parameter "Sequelize" because it is not being used
};
1 change: 1 addition & 0 deletions src/db/migrations/20190821160011-create-comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module.exports = {
}
})
),

down: (queryInterface) => queryInterface.dropTable('comments')
// removed the parameter "Sequelize" because it is not being used
};
1 change: 1 addition & 0 deletions src/db/migrations/20190821160830-create-notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module.exports = {
}
})
),

down: (queryInterface) => queryInterface.dropTable('notifications')
// removed the parameter "Sequelize" because it is not being used
};
1 change: 0 additions & 1 deletion src/db/models/booking.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ module.exports = (sequelize, DataTypes) => {
foreignKey: 'user_id',
onDelete: 'CASCADE'
});

Booking.belongsTo(models.Room, {
foreignKey: 'room_id',
onDelete: 'CASCADE'
Expand Down
2 changes: 0 additions & 2 deletions src/db/models/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ module.exports = (sequelize, DataTypes) => {
tableName: 'comments',
underscored: true
});

Comment.associate = (models) => {
Comment.belongsTo(models.User, {
foreignKey: 'user_id',
onDelete: 'CASCADE'
});

Comment.belongsTo(models.Request, {
foreignKey: 'request_id',
onDelete: 'CASCADE'
Expand Down
1 change: 0 additions & 1 deletion src/db/models/feedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ module.exports = (sequelize, DataTypes) => {
foreignKey: 'user_id',
onDelete: 'CASCADE'
});

Feedback.belongsTo(models.Facility, {
foreignKey: 'facility_id',
onDelete: 'CASCADE'
Expand Down
2 changes: 0 additions & 2 deletions src/db/models/like.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ module.exports = (sequelize) => {
tableName: 'likes',
underscored: true
});

Like.associate = (models) => {
Like.belongsTo(models.User, {
foreignKey: 'user_id',
onDelete: 'CASCADE'
});

Like.belongsTo(models.Facility, {
foreignKey: 'facility_id',
onDelete: 'CASCADE'
Expand Down
1 change: 0 additions & 1 deletion src/db/models/notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ module.exports = (sequelize, DataTypes) => {
foreignKey: 'request_id',
onDelete: 'CASCADE'
});

Notification.belongsTo(models.User, {
foreignKey: 'receiver_id',
onDelete: 'CASCADE'
Expand Down
2 changes: 0 additions & 2 deletions src/db/models/rating.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ module.exports = (sequelize, DataTypes) => {
tableName: 'ratings',
underscored: true
});

Rating.associate = (models) => {
// associations can be defined here
Rating.belongsTo(models.User, {
foreignKey: 'user_id',
onDelete: 'CASCADE'
});

Rating.belongsTo(models.Facility, {
foreignKey: 'facility_id',
onDelete: 'CASCADE'
Expand Down
1 change: 0 additions & 1 deletion src/db/models/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ module.exports = (sequelize, DataTypes) => {
foreignKey: 'user_id',
onDelete: 'CASCADE'
});

Request.belongsTo(models.Booking, {
foreignKey: 'booking_id',
onDelete: 'CASCADE'
Expand Down
1 change: 0 additions & 1 deletion src/db/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ module.exports = (sequelize, DataTypes) => {
type: DataTypes.BOOLEAN,
defaultValue: true
}

}, {
tableName: 'users',
underscored: true
Expand Down
42 changes: 38 additions & 4 deletions src/middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import jwt from 'jsonwebtoken';
import models from '../db/models';

const { User } = models;

const auth = {
verifyToken(token) {
Expand All @@ -16,7 +19,7 @@ const auth = {
let token;

if (req.headers.authorization) {
[, token] = req.headers.authorization.split(' ');
token = req.headers.authorization;
} else if (req.headers['x-access-token']) {
token = req.headers['x-access-token'];
} else if (req.headers.token) {
Expand All @@ -28,7 +31,7 @@ const auth = {
if (!token) {
return res.status(401).json({
status: 'error',
error: 'No token provided.',
error: 'No token provided!',
});
}

Expand All @@ -38,14 +41,45 @@ const auth = {
error: 'Failed to authenticate token.',
});
}

const user = await User.findOne({ where: { id: decoded.payload.id } });
req.currentUser = user;
return next();
} catch (error) {
return res.status(500).json({
status: 'error',
error: ('Internal Server Error'),
});
}
},

async verifyManager(req, res, next) {
try {
let token;

if (req.headers.authorization) {
token = req.headers.authorization;
} else if (req.headers['x-access-token']) {
token = req.headers['x-access-token'];
} else if (req.headers.token) {
token = req.headers.token;
}
const decoded = auth.verifyToken(token);

if (!((decoded.payload.role === 'super_admin') || (decoded.payload.role === 'manager'))) {
return res.status(401).json({
status: 'error',
error: 'Hi! You are not permitted to perform this action',
});
}
return next();
} catch (error) {
return res.status(500).json({
status: 'error',
error: 'Internal Server Error',
error: 'Error Accessing Route',
});
}
}
},
};

export default auth;
18 changes: 18 additions & 0 deletions src/middlewares/requests.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import models from '../db/models';

const { Request } = models;

const requestChecks = {
async validateRequests(req, res, next) {
const request = await Request.count({ where: { id: req.params.id } });
if (request < 1) {
return res.status(404).json({
status: 'error',
error: 'This request does not exist'
});
}
return next();
}
};

export default requestChecks;
2 changes: 2 additions & 0 deletions src/routes/api/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import express from 'express';

import authRouter from './auth.router';
import requestRouter from './requests.router';


const router = express.Router();

router.use('/auth', authRouter);
router.use('/', requestRouter);

export default router;
17 changes: 17 additions & 0 deletions src/routes/api/requests.router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import express from 'express';
import auth from '../../middlewares/auth';
import RequestsController from '../../controllers/requests.controller';
import requestChecks from '../../middlewares/requests.middleware';
import validateRequests from '../../validation/request.validation';

const router = express.Router();

/* Requests Routes Here */
router.patch('/request/:id',
auth.verifyUserToken,
auth.verifyManager,
validateRequests.validateRequestsID,
requestChecks.validateRequests,
RequestsController.rejectRequest);

export default router;
7 changes: 4 additions & 3 deletions src/services/email.service.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import sgMail from '@sendgrid/mail';
import logger from '../logs/winston';

// Setup this key on your .env usDrVXltTtqz6NnsAornNQ.WsLmjMfrwEin01Dj7aQ6xZ14eLqgC5o6lzS_Qw77yFw
// Setup this key on your .env
sgMail.setApiKey(process.env.SEND_GRID_API);

const templates = {
travel_request_notification: 'd-052f3ce066de4a92aa33d254d678e34d',
signup_template: 'd-1ae0bd2e62c742e9a78009512bd1b5b8'
travel_request_notification: 'd-963a476c77a34f318895713712b4d6bb',
signup_template: 'd-1ae0bd2e62c742e9a78009512bd1b5b8',
request_rejected: 'd-ccd25aa2dd9f47cb9d746d909787db59'
};

/**
Expand Down
Loading

0 comments on commit 713d169

Please sign in to comment.