diff --git a/app/controllers/admin/index.js b/app/controllers/admin/index.js new file mode 100644 index 0000000..e650b45 --- /dev/null +++ b/app/controllers/admin/index.js @@ -0,0 +1,3 @@ +module.exports = { + organization: require('./organization.controller') +}; diff --git a/app/controllers/admin/organization.controller.js b/app/controllers/admin/organization.controller.js new file mode 100644 index 0000000..bc71766 --- /dev/null +++ b/app/controllers/admin/organization.controller.js @@ -0,0 +1,9 @@ +const db = require('../../config/db.config.js'), + errorMaker = require('../../helpers/error.maker'); + +const { Grant, Cause, Region, Organization } = db; + +// PUT to change specific org's verify column to true +exports.verifyOrg = (req, res, next) => { + const charity_id = req.params.charity_id; +}; diff --git a/app/controllers/auth.controller.js b/app/controllers/auth.controller.js index 83981ea..a9afe7f 100644 --- a/app/controllers/auth.controller.js +++ b/app/controllers/auth.controller.js @@ -3,34 +3,41 @@ const db = require('../config/db.config.js'), jwt = require('jsonwebtoken'), errorMaker = require('../helpers/error.maker'); -const Donor = db.Donor; +const { Donor, Organization } = db; -// Find a Donor by email + login with JWT -exports.login = (req, res, next) => { - Donor.findAll({ - where: { - email: req.body.email - } - }) - .then(donors => { - if (donors.length < 1) { +// Find a Donor/Org by email + login with JWT +exports.login = (type, role) => (req, res, next) => { + const curr_types = { + donor: Donor, + org: Organization + }; + + curr_types[type] + .findAll({ + where: { + email: req.body.email + } + }) + .then(users => { + if (users.length < 1) { return next(errorMaker(401, 'Invalid or nonexistent email')); } - bcrypt.compare(req.body.password, donors[0].password, (error, result) => { + bcrypt.compare(req.body.password, users[0].password, (error, result) => { if (error) { return next(error); } if (result) { const token = jwt.sign( { - email: donors[0].email, - id: donors[0].id + email: users[0].email, + id: users[0].id, + role: role }, process.env.JWT_KEY ); return res.status(200).json({ message: 'Auth successful', - donor: donors[0], + donor: users[0], token }); } diff --git a/app/controllers/donor/grant.controller.js b/app/controllers/donor/grant.controller.js index 24f9c41..1f75ffd 100644 --- a/app/controllers/donor/grant.controller.js +++ b/app/controllers/donor/grant.controller.js @@ -34,7 +34,7 @@ exports.create = (req, res, next) => { // Find grants with causes, regions, and organizations by donor_id exports.findByDonorId = (req, res, next) => { - const donor_id = req.user_data.id; + const donor_id = req.user.id; Grant.findAll({ where: { diff --git a/app/helpers/roles.js b/app/helpers/roles.js new file mode 100644 index 0000000..7348821 --- /dev/null +++ b/app/helpers/roles.js @@ -0,0 +1,5 @@ +module.exports = { + ADMIN: 'ADMIN', + ORGANIZATION: 'ORGANIZATION', + DONOR: 'DONOR' +}; diff --git a/app/middleware/check-auth.js b/app/middleware/check-auth.js index 38211ab..95e0e96 100644 --- a/app/middleware/check-auth.js +++ b/app/middleware/check-auth.js @@ -1,11 +1,15 @@ const jwt = require('jsonwebtoken'), errorMaker = require('../helpers/error.maker'); -module.exports = (req, res, next) => { +module.exports = role => (req, res, next) => { try { const token = req.headers.authorization.split(' ')[1]; const decoded = jwt.verify(token, process.env.JWT_KEY); - req.user_data = decoded; //for use till end of request + req.user = decoded; //for use till end of request + + if (role != req.user.role) { + throw new Error(); + } next(); } catch (error) { diff --git a/app/models/donor.model.js b/app/models/donor.model.js index defba63..d25d2ed 100644 --- a/app/models/donor.model.js +++ b/app/models/donor.model.js @@ -9,7 +9,6 @@ module.exports = (sequelize, DataTypes) => { type: DataTypes.STRING, allowNull: false }, - middle_name: DataTypes.STRING, last_name: { type: DataTypes.STRING, allowNull: false diff --git a/app/models/grant.model.js b/app/models/grant.model.js index 453ed5f..a2f6f31 100644 --- a/app/models/grant.model.js +++ b/app/models/grant.model.js @@ -20,7 +20,8 @@ module.exports = (sequelize, DataTypes) => { }, monthly: { type: DataTypes.BOOLEAN, - allowNull: false + allowNull: false, + defaultValue: false }, num_causes: { type: DataTypes.INTEGER, diff --git a/app/models/organization.model.js b/app/models/organization.model.js index 4bb080b..3cfbde9 100644 --- a/app/models/organization.model.js +++ b/app/models/organization.model.js @@ -6,6 +6,30 @@ module.exports = (sequelize, DataTypes) => { autoIncrement: true }, name: { type: DataTypes.STRING, allowNull: false }, + first_name: { + type: DataTypes.STRING, + allowNull: false + }, + last_name: { + type: DataTypes.STRING, + allowNull: false + }, + email: { + type: DataTypes.STRING, + validate: { + isEmail: true + }, + allowNull: false + }, + password: { + type: DataTypes.STRING, + allowNull: false + }, + verified: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, short_description: DataTypes.STRING, primary_cause: { type: DataTypes.STRING, allowNull: false }, primary_region: { type: DataTypes.STRING, allowNull: false }, diff --git a/app/routes/admin.route.js b/app/routes/admin.route.js new file mode 100644 index 0000000..73fdfe8 --- /dev/null +++ b/app/routes/admin.route.js @@ -0,0 +1,15 @@ +const express = require('express'), + router = express.Router(), + checkAuth = require('../middleware/check-auth'), + roles = require('../helpers/roles'); + +const controllers = require('../controllers/admin'); + +// PUT Manual verification of a charity +router.put( + '/org/:charity_id', + checkAuth(roles.ADMIN), + controllers.organization.verifyOrg +); + +module.exports = router; diff --git a/app/routes/auth.route.js b/app/routes/auth.route.js index d1d5e3c..2d6e87a 100644 --- a/app/routes/auth.route.js +++ b/app/routes/auth.route.js @@ -1,10 +1,14 @@ const express = require('express'), router = express.Router(), - checkAuth = require('../middleware/check-auth'); + checkAuth = require('../middleware/check-auth'), + roles = require('../helpers/roles'); const auth = require('../controllers/auth.controller.js'); -// Check database for donor -router.post('/donor/login', auth.login); +// Check database for donor and get token with donor role +router.post('/donor/login', auth.login('donor', roles.DONOR)); + +// Check database for org and get token with org role +router.post('/org/login', auth.login('org', roles.ORGANIZATION)); module.exports = router; diff --git a/app/routes/donor.route.js b/app/routes/donor.route.js index ad16957..d4171f4 100644 --- a/app/routes/donor.route.js +++ b/app/routes/donor.route.js @@ -1,6 +1,7 @@ const express = require('express'), router = express.Router(), - checkAuth = require('../middleware/check-auth'); + checkAuth = require('../middleware/check-auth'), + roles = require('../helpers/roles'); const controllers = require('../controllers/donor'); @@ -8,33 +9,41 @@ const controllers = require('../controllers/donor'); router.post('/', controllers.donor.create); // GET Retrieve all Donors -router.get('/', checkAuth, controllers.donor.findAll); +router.get('/', checkAuth(roles.DONOR), controllers.donor.findAll); // GET Retrieve grants with causes and regions and charities details by donor_id -router.get('/grants/', checkAuth, controllers.grant.findByDonorId); +router.get('/grants/', checkAuth(roles.DONOR), controllers.grant.findByDonorId); /** POST Create grants with following body: * - list of id's of selected causes and regions * - FINAL list of id's of selected organizations * - donor_id * */ -router.post('/grants/:donor_id', checkAuth, controllers.grant.create); +router.post( + '/grants/:donor_id', + checkAuth(roles.DONOR), + controllers.grant.create +); // DELECT a grant of a donor -router.delete('/grants/:grant_id', checkAuth, controllers.grant.delete); +router.delete( + '/grants/:grant_id', + checkAuth(roles.DONOR), + controllers.grant.delete +); // POST to get suggested organizations to distribute to // running "the algorithm" router.post( '/organizations/', - checkAuth, + checkAuth(roles.DONOR), controllers.organization.findSuggested ); // GET min and optimal amount to choose router.get( '/organizations/amounts', - checkAuth, + checkAuth(roles.DONOR), controllers.organization.findAmounts ); diff --git a/server.js b/server.js index d0cc6a3..dec5469 100644 --- a/server.js +++ b/server.js @@ -53,6 +53,8 @@ app.use('/api/donors', require('./app/routes/donor.route.js')); app.use('/api/auth', require('./app/routes/auth.route.js')); //general routes app.use('/api', require('./app/routes/general.route.js')); +//admin routes +app.use('/admin', require('./app/routes/admin.route')); //404 not found error handling on any other routes app.use((req, res, next) => {