Skip to content

Commit

Permalink
fix(profile-update): return new token upon profile update
Browse files Browse the repository at this point in the history
- return new token upon profile update
- implement change full name endpoint

[Fixes #!7]
  • Loading branch information
jkarenzi committed Aug 30, 2024
1 parent 28d863b commit db2fb21
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 13 deletions.
4 changes: 2 additions & 2 deletions __tests__/userController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe('User Controller tests', () => {

expect(res.status).toBe(200);
expect(res.body.message).toBe('Email successfully updated');
expect(res.body.data.email).toBe('[email protected]');
expect(res.body.data.token).toBeDefined();
});

it('should return 400 if email validation fails', async () => {
Expand Down Expand Up @@ -214,6 +214,6 @@ describe('User Controller tests', () => {
.delete('/api/users/profileImg')
.set('Authorization', `Bearer ${token}`)

expect(res.status).toBe(204);
expect(res.status).toBe(200);
})
});
7 changes: 4 additions & 3 deletions src/controllers/authController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ const toggleTwoFactorAuth = errorHandler(async (req:Request, res:Response) => {
const formData = req.body

const validationResult = updateTwoFactorAuthSchema.validate(formData);

if (validationResult.error) {
return res
.status(400)
Expand All @@ -185,9 +185,10 @@ const toggleTwoFactorAuth = errorHandler(async (req:Request, res:Response) => {
});
}

await User.findByIdAndUpdate(userId, {'twoFactorAuth.isEnabled':formData.status},{new:true})
const updatedUser = await User.findByIdAndUpdate(userId, {'twoFactorAuth.isEnabled':formData.status},{new:true})
const token = await jwt.sign({ user:updatedUser }, jwtSecret, { expiresIn: '1h' });

return res.status(200).json({status:'success',message:'Update successful'})
return res.status(200).json({status:'success',message:'Update successful', data:{token}})
})

module.exports = {
Expand Down
42 changes: 36 additions & 6 deletions src/controllers/userController.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Request, Response } from 'express';
import { IUser } from '../custom';
const { errorHandler } = require('../middleware/errorHandler');
const User = require('../models/User')
const bcrypt = require('bcrypt')
const {updatePasswordSchema, updateEmailSchema} = require('../middleware/validators/userSchema')
const {updatePasswordSchema, updateEmailSchema, updateFullNameSchema} = require('../middleware/validators/userSchema')
const cloudinary = require('../middleware/cloudinary')
const jwt = require('jsonwebtoken')
require('dotenv').config()


const jwtSecret = process.env.JWT_SECRET

interface cloudinaryUploadResult {
public_id: string,
Expand Down Expand Up @@ -72,9 +78,27 @@ const changeEmail = errorHandler(async (req: Request, res: Response) => {
}

const updatedDoc = await User.findByIdAndUpdate(userId,{email:formData.newEmail},{new:true})
return res.status(200).json({status:'success', message: 'Email successfully updated', data:{email:updatedDoc.email}})
const token = await jwt.sign({ user:updatedDoc }, jwtSecret, { expiresIn: '1h' });
return res.status(200).json({status:'success', message: 'Email successfully updated', data:{token}})
});

const changeFullName = errorHandler(async (req: Request, res: Response) => {
const formData = req.body
const userId = req.user!._id

const validationResult = updateFullNameSchema.validate(formData)

if(validationResult.error){
return res.status(400).json({status:'error', message:validationResult.error.details[0].message})
}

const updatedUser = await User.findByIdAndUpdate(userId,{fullName:formData.fullName},{new:true})
const token = await jwt.sign({ user:updatedUser }, jwtSecret, { expiresIn: '1h' });

return res.status(200).json({status:'success', data:{token}})

})

const changeProfileImg = errorHandler(async (req: Request, res: Response) => {
const userId = req.user!._id
const user = await User.findOne({_id:userId})
Expand Down Expand Up @@ -108,7 +132,9 @@ const changeProfileImg = errorHandler(async (req: Request, res: Response) => {
{new:true}
)

return res.status(200).json({status:'success', message:'Profile Image successfully updated', data:{profileImg:updatedUser.profileImg}})
const token = await jwt.sign({ user:updatedUser }, jwtSecret, { expiresIn: '1h' });

return res.status(200).json({status:'success', message:'Profile Image successfully updated', data:{token}})
});

const removeProfileImg = errorHandler(async (req: Request, res: Response) => {
Expand All @@ -121,18 +147,21 @@ const removeProfileImg = errorHandler(async (req: Request, res: Response) => {

const result = await cloudinary.uploader.destroy(user.profileImg.publicId,{invalidate:true})

let updatedUser: IUser;
if(result.result === 'ok'){
await User.findByIdAndUpdate(
updatedUser = await User.findByIdAndUpdate(
user._id,
{
profileImg: {
publicId: 'default',
url: process.env.DEFAULT_PROFILE_IMG
}
}
},
{new:true}
)

return res.status(204).json({})
const token = await jwt.sign({ user:updatedUser }, jwtSecret, { expiresIn: '1h' });
return res.status(200).json({status:'success', message:"Profile image successfully removed", data:{token}})
}else{
return res.status(400).json({status:'error', message:'An error occured. Try again later'})
}
Expand All @@ -151,6 +180,7 @@ const deleteUser = errorHandler(async (req: Request, res: Response) => {
module.exports = {
getAllUsers,
getUser,
changeFullName,
changeEmail,
changePassword,
changeProfileImg,
Expand Down
13 changes: 12 additions & 1 deletion src/middleware/validators/userSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,18 @@ const updateEmailSchema = Joi.object({
newEmail: Joi.string().email().required(),
})

const updateFullNameSchema = Joi.object({
fullName: Joi.string()
.regex(/^[A-Za-z\s]{5,}$/)
.message(
'fullName can only contain letters and should have atleast 5 characters'
)
.required()
})


module.exports = {
updateEmailSchema,
updatePasswordSchema
updatePasswordSchema,
updateFullNameSchema
}
4 changes: 3 additions & 1 deletion src/routes/userRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ const {
changePassword,
changeProfileImg,
removeProfileImg,
deleteUser
deleteUser,
changeFullName
} = require('../controllers/userController')
import { Router } from 'express';
const authenticateToken = require('../middleware/authenticateToken')
Expand All @@ -16,6 +17,7 @@ const userRouter = Router();

userRouter.use(authenticateToken)

userRouter.patch('/fullName', changeFullName)
userRouter.patch('/email', changeEmail)
userRouter.patch('/password', changePassword)
userRouter.route('/profileImg').patch(upload.fields([{name:'image'}]), changeProfileImg).delete(removeProfileImg)
Expand Down

0 comments on commit db2fb21

Please sign in to comment.