Skip to content

Commit

Permalink
feat(endpoint): Set up User Profile setting
Browse files Browse the repository at this point in the history
 - this allows a user to view and edit his/her profile details only.
   [delivers #167891580]
  • Loading branch information
femitj committed Sep 3, 2019
1 parent 8a0778c commit e67f6dc
Show file tree
Hide file tree
Showing 7 changed files with 573 additions and 7 deletions.
125 changes: 125 additions & 0 deletions src/controllers/Profile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import db from '../database/models';
import Response from '../helpers/Response';

const { User, Company } = db;

/** user profile class */
class Profile {
/**
*
* @param {req} req
* @param {res} res
* @returns {object} object
*/
static async getProfile(req, res) {
try {
const { payload } = req.payload;
const { email } = payload;

const user = await User.findOne({ where: { email } });
const {
firstName, lastName, gender, dob, companyId
} = user;

const company = await Company.findOne({ where: { id: companyId } });
const {
name, address
} = company;

const response = new Response(
true,
200,
'User Profile retrieved successfuly',
{
profile: {
firstName,
lastName,
gender,
dob,
companyName: name,
address
}
}
);
return res.status(response.code).json(response);
} catch (err) {
const response = new Response(
false,
500,
'Server error, Please try again later',
);
return res.status(response.code).json(response);
}
}

/**
*
* @param {req} req
* @param {res} res
* @returns {object} object
*/
static async updateProfile(req, res) {
try {
const { payload } = req.payload;
const { email, role, id } = payload;
const {
firstName, lastName, gender, dob, companyName, address
} = req.body;

await User.update(
{
firstName, lastName, gender, dob
},
{
where: { email },
returning: true,
}
);

if (role === 'staff') {
const response = new Response(
true,
200,
'User Profile updated successfuly',
{
profile: {
firstName, lastName, gender, dob
}
}
);
return res.status(response.code).json(response);
}

if (role === 'owner') {
await Company.update(
{ name: companyName, address },
{
where: { owner: id },
returning: true,
}
);

const response = new Response(
true,
200,
'Admin Profile updated successfuly',
{
profile: {
firstName, lastName, gender, dob, companyName, address
}
}
);
return res.status(response.code).json(response);
}
} catch (err) {
const response = new Response(
false,
500,
'Server error, Please try again later',
);
return res.status(response.code).json(response);
}
}
}

export default Profile;
2 changes: 2 additions & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Router } from 'express';
import authRoute from './user.routes';
import tripRoute from './trip.routes';
import profileRoute from './profile.routes';

const router = Router();

router.use('/auth', authRoute);
router.use('/trips', tripRoute);
router.use(profileRoute);

export default router;
25 changes: 25 additions & 0 deletions src/routes/profile.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Router } from 'express';
import Profile from '../controllers/Profile';
import profileSchema from '../validation/profileSchema';
import validator from '../middlewares/validator';
import middleware from '../middlewares/AuthMiddlewares';
import tokenHelper from '../helpers/Token';

const profileRoute = Router();

profileRoute.get(
'/profile',
tokenHelper.verifyToken,
middleware.isUserVerified,
Profile.getProfile,
);

profileRoute.patch(
'/profile',
validator(profileSchema),
tokenHelper.verifyToken,
middleware.isUserVerified,
Profile.updateProfile,
);

export default profileRoute;
54 changes: 54 additions & 0 deletions src/validation/profileSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { check } from 'express-validator';
import capitalize from '../utils/capitalize';

const dateRegex = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/;

/* eslint-disable arrow-parens */
const profileSchema = [
check('firstName')
.optional().trim()
.isLength({ min: 2, max: 15 })
.withMessage('First name should be between 2 to 15 characters')
.isAlpha()
.withMessage('First name should only contain alphabets')
.customSanitizer(value => capitalize(value)),

check('lastName')
.optional().trim()
.isLength({ min: 2, max: 15 })
.withMessage('Last name should be between 2 to 15 characters')
.isAlpha()
.withMessage('Last name should only contain alphabets')
.customSanitizer(value => capitalize(value)),

check('dob')
.optional().matches(dateRegex)
.withMessage("Date must be of the format 'yyyy-mm-dd'")
.custom(value => {
const year = value.substring(0, 4);
const today = new Date().getFullYear();
if ((today - year) < 18) {
return false;
}
return true;
})
.withMessage('Users must be 18 and above'),

check('gender')
.optional()
.matches(/^(male|m|female|f)$/)
.withMessage('Male or Female is the accepted value'),

check('companyName')
.optional().trim()
.isLength({ min: 1 })
.customSanitizer(value => capitalize(value)),

check('address')
.optional().trim()
.isLength({ min: 2, max: 100 })
.withMessage('Address should be between 2 to 100 characters')
.customSanitizer(value => capitalize(value))
];

export default profileSchema;
126 changes: 126 additions & 0 deletions swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
{
"name": "auth",
"description": "Operations related to Users authentication"
},
{
"name": "Profile",
"description": "Operations related to Users profile"
}
],
"paths": {
Expand Down Expand Up @@ -402,6 +406,92 @@
}
}
}
},
"/profile": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"tags": [
"Profile"
],
"summary": "Retrieve user profile",
"operationId": "getUserProfile",
"parameters": [
{
"in": "query",
"name": "token",
"schema": {
"type": "string"
},
"description": "user signup token",
"required": true
}
],
"responses": {
"200": {
"description": "User Profile retrieved successfuly"
},
"401": {
"description": "Unathorized, You did not provide a token"
},
"500": {
"description": "Server error, please try again later"
}
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"tags": [
"Profile"
],
"summary": "Update user profile",
"operationId": "patchUserProfile",
"parameters": [
{
"in": "query",
"name": "token",
"schema": {
"type": "string"
},
"description": "user signup token",
"required": true
}
],
"requestBody": {
"description": "user object",
"content": {
"application/xml": {
"schema": {
"$ref": "#/components/schemas/Profile"
}
},
"application/json": {
"schema": {
"$ref": "#/components/schemas/Profile"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "User Profile updated successfuly"
},
"401": {
"description": "Unathorized, You did not provide a token"
},
"500": {
"description": "Server error, please try again later"
}
}
}
}
},
"components": {
Expand Down Expand Up @@ -482,8 +572,44 @@
"code": {
"type": "string"
}
},
"xml": {
"name": "login"
}
},
"Profile": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"gender": {
"type": "string"
},
"dob": {
"type": "string"
},
"companyName": {
"type": "string"
},
"address": {
"type": "string"
}
},
"xml": {
"name": "Profile"
}
}
},
"securitySchemes": {
"ApiKeyAuth": {
"type": "apiKey",
"in": "header",
"name": "authorization"
}
}
}
}
Loading

0 comments on commit e67f6dc

Please sign in to comment.