Skip to content

Commit

Permalink
Merge pull request #9 from BuildForSDGCohort2/authentication
Browse files Browse the repository at this point in the history
authenticatin and authorization started
  • Loading branch information
udofia2 authored Sep 17, 2020
2 parents 20aa3e2 + 8c71ac8 commit 0077c85
Show file tree
Hide file tree
Showing 13 changed files with 396 additions and 16 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# TEAM-050-Backend

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2fe1c96bb8af4f7eae751c4dfe431187)](https://app.codacy.com/gh/BuildForSDGCohort2/TEAM-050-Backend?utm_source=github.com&utm_medium=referral&utm_content=BuildForSDGCohort2/TEAM-050-Backend&utm_campaign=Badge_Grade_Settings)

## A platform for Nigerian Citizens to easily have access to their criminal records.

## Pre-Requisites

- MongoDB and database created

## How to Install and run the application

- Clone the application and run `npm install`
- Run `cp config/default.examples.js config/default.js ` to create the default variables and fill them
- Run `npm run dev` to start development server

## API Documentation

- [API Documentation](https://documenter.getpostman.com/view/7592361/TVK8c19z)

## Technologies Used

- NodeJS / Express
- Mongo Database
- Postman

## Author

- [UDOFIA](https://github.com/udofia2)-dev)

34 changes: 26 additions & 8 deletions api/controller/citizen.Controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,32 @@ const citizenActions = (Citizens, bcrypt, mySecrete, jwt, validationResult) => {
}
};


/**
* @param GET /api/v1/citizen/profile/:id
* @desc displays citizens dashboard
* @access public( only signed in citizens can access)
*/
const profile = async (req, res) => {
const citizen = await Citizens.findOne({_id: req.params.id})
res.json(citizen);
};

/**
* @param PATCH /api/v1/citizen/edit/:id
* @desc citizen can logout of the platform
* @access protected( only logged in citizen can access)
*/
const update = async (req, res) => {
const citizen = await Citizens.findByIdAndUpdate(req.params.id, req.body)
res.json({
msg: "citizen had been edited, your profile is now updated.",
citizen
})
};


/**
* @param DELETE /api/v1/citizen/delete/:id
* @desc gives citizen the ability to delete their account from the platform
* @access protected( only signed in citizens and admin can access this route)
Expand All @@ -188,14 +213,6 @@ const citizenActions = (Citizens, bcrypt, mySecrete, jwt, validationResult) => {
});
};

/**
* @param GET /api/v1/citizen/profile/:id
* @desc displays citizens dashboard
* @access public( only signed in citizens can access)
*/
const profile = async (req, res) => {
res.json("citizen can view profile");
};

/**
* @param POST /api/v1/citizen/logout
Expand All @@ -213,6 +230,7 @@ const citizenActions = (Citizens, bcrypt, mySecrete, jwt, validationResult) => {
login,
logout,
profile,
update
};
};

Expand Down
251 changes: 251 additions & 0 deletions api/controller/officer.Controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
const officerActions = (Officers, bcrypt, validationResult, jwt, mySecrete) => {
/**
* @param GET /api/v1/officer
* @desc displays all the registered officers
* @access private( only super officer can access)
*/
const officers = async (req, res) => {
try {
const officers = await Officers.find({});
res.status(200).json({
msg: 'Testing the route',
totalOfficers: officers.length,
officers: officers.map((officer) => {
return {
officer,
request: {
"view Officer": {
type: "GET",
url: `http://localhost:3000/api/v1/officer/profile/${officer._id}`,
description:
"Click on the url to view all the detail about this officer",
},
"Add an Officer": {
type: "POST",
url: "http://localhost:3000/api/v1/officer/register",
description:
"Follow the provided url to make a registration. If you are using postman to, the request will be a post request",
},
Login: {
type: "POST",
url: "http://localhost:3000/api/v1/officer/login",
description:
"Registered officers can follow the provided url to login to their profile page. If you are using postman to, the request will be a post request",
},
"Remove an Officer": {
type: "DELETE",
url: `http://localhost:3000/api/v1/officer/delete/${officer._id}`,
description:
"Registered citizens can follow the provided url to login to their profile page. If you are using postman to, the request will be a post request",
},
},
};
}),
});

} catch (err) {
res.status(500).json(err)

}
};

/**
* @param POST /api/v1/officer/register
* @desc Add an officer here
* @access private( Everyone can access)
*/
const register = async (req, res) => {
console.log('officer route')
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}

try {
const {
name,
email,
password,
gender
} = req.body;

const user = await Officers.findOne({ email });

if (user) return res.status(400).json(`${email} is already in use`);

const officer = new Officers({
name,
email,
password,
gender
});

const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(password, salt);
officer.password = hash;

await officer.save();

res.status(201).json({
msg: `${officer.name.first} ${officer.name.last} is successfully registered`,
request: {
Login: {
type: "POST",
url: "http://localhost:3000/api/v1/officer/login",
description:
"Registered officer can follow the provided url to login to their profile page. If you are using postman to, the request will be a post request",
},
},
});
} catch (err) {
res.status(500).json(err);
}
};

/**
* @param POST /api/v1/officer/login
* @desc officer login route
* @access public( Everyone can access)
*/
const login = async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}

try {
const { email, password } = req.body;

if(!(email && password)) return res.status(404).json('Please fill in your email and password')

const user = await Officers.findOne({ email });


if (!user)
return res.status(401).json({
msg: `Invalid Credentials`,
request: {
Register: {
type: "POST",
url: "http://localhost:3000/api/v1/officer/register",
description:
"Follow the provided url to make a registration. If you are using postman to, the request will be a post request",
},
},
});

const isMatch = await bcrypt.compare(password, user.password);


if(!isMatch){
return res.status(401).json({
msg: `Invalid Credentials`,
request: {
Register: {
type: "POST",
url: "http://localhost:3000/api/v1/officer/register",
description:
"Follow the provided url to make a registration. If you are using postman to, the request will be a post request",
},
},
});
}
const payload = {
user: user._id,
};

const token = jwt.sign(payload, mySecrete, { expiresIn: "1hr" });
const heads = await res.setHeader("x-auth-header", token);


res.status(200).json({
msg: `Welcome back officer ${user.name.first}`,
token,
heads,
});
} catch (err) {
res.status(500).json(err);
}
};

/**
* @param DELETE /api/v1/officer/delete/:id
* @desc Affords officers to priviledge to exit the platform
* @access protected( only signed in officers and seniorOfficers can access this route)
*/
const deltOfficer = async (req, res) => {
const officer = await Officers.findByIdAndDelete(req.params.id);
res.status(200).json({
// msg: `${officer.name.first} ${officer.name.last} with the id ${officer._id} is successfully deleted from the database`,
msg: 'delted',
request: {
Register: {
type: "POST",
url: "http://localhost:3000/api/v1/officer/register",
description:
"Follow the provided url to make a registration. If you are using postman to, the request will be a post request",
},
Login: {
type: "POST",
url: "http://localhost:3000/api/v1/officer/login",
description:
"Registered officer can follow the provided url to login to their profile page. If you are using postman to, the request will be a post request",
},
},
});
};

/**
* @param GET /api/v1/citizen/profile/:id
* @desc displays citizens dashboard
* @access public( only signed in citizens can access)
*/
const profile = async (req, res) => {
try {
const officer = await Officers.findOne({_id: req.params.officerID})
res.json(officer);
} catch (err) {
res.status(500).json(err)

}
};


/**
* @param PATCH /api/v1/citizen/edit/:id
* @desc displays citizens dashboard
* @access public( only signed in citizens can access)
*/
const update = async (req, res) => {
try {
const officer = await Officers.findOneAndUpdate({_id: req.params.officerID}, req.body)
res.json(officer);
} catch (err) {
res.status(500).json(err)
}
};


/**
* @param POST /api/v1/citizen/logout
* @desc citizen can logout of the platform
* @access protected( only logged in citizen can access)
*/
const logout = async (req, res) => {

res.json("citizen can logout");
};

return {
deltOfficer,
officers,
register,
login,
logout,
profile,
update
};
};

module.exports = officerActions;

3 changes: 3 additions & 0 deletions api/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const authorized = () => {};

module.exports = authorized;
12 changes: 5 additions & 7 deletions api/middleware/formValidation.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
const { validationResult } = require("express-validator");

const validation = (body) => {
const validation = (check) => {
const regForm = [
body("email").isEmail(),
body("password").isLength({ min: 5 }),
check("email").isEmail(),
check("password").isLength({ min: 5 }),
];

const loginForm = [
body("email").isEmail(),
body("password").not().notEmpty(),
check("email").isEmail(),
check("password").not().notEmpty(),
];
return {
regForm,
Expand Down
30 changes: 30 additions & 0 deletions api/model/officer.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const mongoose = require('mongoose')

const { Schema } = mongoose

const officer = new Schema({
name: {
first: {
type: String,
required: true
},
last: {
type: String,
require: true
}
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
gender: String,

},{
timestamps: true
})

module.exports = mongoose.model('officers', officer)
Empty file.
Loading

0 comments on commit 0077c85

Please sign in to comment.