Skip to content

Commit

Permalink
Merge 8cdc450 into 66b51cf
Browse files Browse the repository at this point in the history
  • Loading branch information
adafia committed Jul 11, 2019
2 parents 66b51cf + 8cdc450 commit bf9bdb1
Show file tree
Hide file tree
Showing 13 changed files with 390 additions and 18 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ However, for the purpose of testing and configurations, one endpoint has been cr

> create database to postgresql
```
> createdb authorshavendb
> createdb authorsHavenDb
```
remember to change the password in config.js file for development

Expand Down
11 changes: 5 additions & 6 deletions example.env
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
DATABASE_USERNAME_DEV="your-database-username"
DATABASE_PASSWORD="your-database-password"
DATABASE_PASSWORD_TEST="your-postgres-password-test"
SECRET_JWT_KEY="your-own-secret-key"

DATABASE_USERNAME_TEST="your-database-username-for-test"
DATABASE_PASSWORD_TEST="your-postgres-password-test"

SENDGRID_API_KEY="insert your send grid token"
SECRET_JWT_KEY='write your secret key'
SECRET_JWT_KEY="your-own-secret-key"
SECRET_KEY="your-database-password"
DATABASE_PASSWORD_TEST="password"
DATABASE_USERNAME_TEST="postgres"

HEROKU_DATABASE_USERNAME="heroku-database-username"
HEROKU_SECRET_KEY="heroku-database-password"
HEROKU_HOST="heroku-host"
HEROKU_DATABASE="heroku-database-name"
SendGridKey=""

HOST="127.0.0.1:7000"
59 changes: 59 additions & 0 deletions src/controllers/profileController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import model from '../db/models/index';

const { Users } = model;

/**
* profile controller
*/
class ProfileManager {
/**
*
* @param {Object} req
* @param {Object} res
* @returns {Object} success user view profile
*/
static async viewProfile(req, res) {
const user = await Users.findOne({ where: { username: req.params.username } });
if (user) {
user.hash = undefined;
return res.status(200).json({
profile: user
});
}
return res.status(404).json({
message: 'user with that email does not exist'
});
}

/**
*
* @param {Object} req
* @param {Object} res
* @returns {Object} success user update profile
*/
static async updateProfile(req, res) {
try {
const {
email, username, image, bio, isVerified
} = req.body;
const user = await Users.findOne({ where: { username: req.params.username } });
const updated = await user.update({
email: email || user.email,
username: username || user.username,
image: image || user.image,
bio: bio || user.bio,
isVerified: isVerified || user.isVerified
});
updated.hash = undefined;
return res.status(200).json({
user: updated
});
} catch (error) {
return res.json({
error
});
}
}
}

export default ProfileManager;
1 change: 0 additions & 1 deletion src/controllers/userControllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class UserManager {
message: 'Thank you for registration, You should check your email for verification',
});
} catch (error) {
console.log(error);
return res.status(409).json({
message: 'user with the same email already exist'
});
Expand Down
6 changes: 0 additions & 6 deletions src/db/config/envirnoment.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,4 @@ envConfig.db_password_pro = process.env.HEROKU_SECRET_KEY;
envConfig.db_host_pro = process.env.HEROKU_HOST;
envConfig.db_database_pro = process.env.HEROKU_DATABASE;

envConfig.send_grid_key = process.env.SendGridApiKey;
envConfig.host = process.env.HOST;
envConfig.token = process.env.SECRET_JWT_KEY;
envConfig.email = process.env.EMAIL;
envConfig.password = process.env.PASSWORD;

export default envConfig;
2 changes: 1 addition & 1 deletion src/db/models/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default (sequelize, DataTypes) => {
}
},
bio: DataTypes.STRING,
image: DataTypes.STRING,
image: DataTypes.BLOB('long'),
favorites: [{
type: DataTypes.STRING,
allowNull: {
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/processToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class processToken {
* @returns {object} token
*/
static async signToken(payload) {
const token = await jwt.sign(payload, process.env.SECRET_JWT_KEY, { expiresIn: 60 });
const token = await jwt.sign(payload, process.env.SECRET_JWT_KEY, { expiresIn: '24h' });
return token;
}

Expand All @@ -22,7 +22,7 @@ class processToken {
* @returns {object} verified token
*/
static async verifyToken(token) {
const verifyToken = await jwt.verify(token, process.env.SECRET_JWT_KEY, { expiresIn: 60 });
const verifyToken = await jwt.verify(token, process.env.SECRET_JWT_KEY, { expiresIn: '24h' });
return verifyToken;
}
}
Expand Down
43 changes: 43 additions & 0 deletions src/middlewares/isAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import processToken from '../helpers/processToken';

/**
* authenticate user
*/
class isAuth {
/**
*
* @param {object} req
* @param {object} res
* @param {object} next
* @returns {object} user details
*/
static async hasToken(req, res, next) {
const { token } = req.headers;
if (!token) {
return res.status(401).json({
message: 'unauthorized'
});
}
next();
}

/**
*
* @param {object} req
* @param {object} res
* @param {object} next
* @returns {object} user details
*/
static async isOwner(req, res, next) {
const { token } = req.headers;
const { username } = await processToken.verifyToken(token);
if (username !== req.params.username) {
return res.status(403).json({
message: 'Forbidden access'
});
}
next();
}
}

export default isAuth;
3 changes: 2 additions & 1 deletion src/routes/api/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import express from 'express';

import users from './users';
import profiles from './profiles';

const router = express.Router();

router.use('/api', users);
router.use('/api', profiles);

export default router;
10 changes: 10 additions & 0 deletions src/routes/api/profiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import express from 'express';
import profileController from '../../controllers/profileController';
import isAuth from '../../middlewares/isAuth';

const router = express.Router();

router.get('/profile/:username', isAuth.hasToken, profileController.viewProfile);
router.put('/profiles/:username', isAuth.hasToken, isAuth.isOwner, profileController.updateProfile);

export default router;
1 change: 1 addition & 0 deletions src/routes/api/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import logout from '../../middlewares/logout';

const { logoutToken } = logout;


const router = express.Router();

router.post('/verification', userController.verification);
Expand Down
105 changes: 105 additions & 0 deletions swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,36 @@
"type": "text"
}
}
},
"view-profile": {
"required": [
"username",
"token"
],
"properties": {
"username": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"update-profile": {
"properties": {
"username": {
"type": "string"
},
"email": {
"type": "string"
},
"image": {
"type": "string"
},
"bio": {
"type": "string"
}
}
}
},
"paths": {
Expand Down Expand Up @@ -201,6 +231,81 @@
}
}
},
"/api/profile/{username}": {
"get": {
"tags": [
"view profile"
],
"description": "A user can view his or her profile and that of other users",
"parameters": [
{
"name": "username",
"in": "path",
"description": "A user can view his or her profile and that of other users by specifing the username",
"require": true
},
{
"name": "token",
"in": "header",
"description": "Token to authorized user",
"require": true
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "user profile fetched successfully",
"schema": {
"$ref": "#/definitions/view-profile"
}
}
}
}
},
"/api/profiles/{username}": {
"put": {
"tags": [
"update profile"
],
"description": "A user can update his or her profile and that of other users",
"parameters": [
{
"name": "username",
"in": "path",
"description": "A user can update his or her profile and that of other users by specifing the username",
"require": true
},
{
"name": "token",
"in": "header",
"description": "Token to authorized user",
"require": true
},
{
"name": "body",
"in": "body",
"description": "A user can update his or her profile and that of other users",
"require": true,
"schema": {
"$ref": "#/definitions/update-profile"
}
}
],
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "user profile updated successfully",
"schema": {
"$ref": "#/definitions/update-profile"
}
}
}
}
},
"/api/users/login": {
"post": {
"tags": [
Expand Down
Loading

0 comments on commit bf9bdb1

Please sign in to comment.