backend: PUT /users - Modifier le profil
This commit is contained in:
		| @@ -10,7 +10,6 @@ exports.postFunction = (req, res, next) => { | ||||
|     const image = req.files.image; | ||||
|     const errors = validationResult(req); | ||||
|     if (!errors.isEmpty()) { | ||||
|         console.log(errors.array()) | ||||
|         return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 }); | ||||
|     } | ||||
|     if (!image || image.truncated && ( | ||||
| @@ -28,7 +27,7 @@ exports.postFunction = (req, res, next) => { | ||||
|             return res.status(201).json({ message: "La fonction a été correctement ajouté!"}); | ||||
|         } catch (error) { | ||||
|             console.log(error); | ||||
|             errorHandling(next, serverError); | ||||
|             return errorHandling(next, serverError); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
| @@ -48,6 +47,6 @@ exports.deleteFunction = async (req, res, next) => { | ||||
|         res.status(200).json({ message: "La fonction a été correctement supprimé!"}); | ||||
|     } catch (error) { | ||||
|         console.log(error); | ||||
|         errorHandling(next, serverError); | ||||
|         return errorHandling(next, serverError); | ||||
|     } | ||||
| } | ||||
| @@ -8,6 +8,6 @@ exports.getCategories = (_req, res, next) => { | ||||
|         }) | ||||
|         .catch((error) => { | ||||
|             console.log(error); | ||||
|             errorHandling(next, serverError); | ||||
|             return errorHandling(next, serverError); | ||||
|         }); | ||||
| } | ||||
| @@ -37,7 +37,8 @@ exports.getFunctions = (req, res, next) => { | ||||
|         ], | ||||
|         attributes: { | ||||
|             exclude: ["updatedAt", "utilizationForm", "article", "isOnline"] | ||||
|         } | ||||
|         }, | ||||
|         order: [['createdAt', 'DESC']] | ||||
|     }) | ||||
|         .then((result) => { | ||||
|             const { count, rows } = result; | ||||
| @@ -46,7 +47,7 @@ exports.getFunctions = (req, res, next) => { | ||||
|         }) | ||||
|         .catch((error) => { | ||||
|             console.log(error); | ||||
|             errorHandling(next, serverError); | ||||
|             return errorHandling(next, serverError); | ||||
|         }); | ||||
| } | ||||
|  | ||||
| @@ -69,7 +70,7 @@ exports.getFunctionBySlug = (req, res, next) => { | ||||
|         }) | ||||
|         .catch((error) => { | ||||
|             console.log(error); | ||||
|             errorHandling(next, serverError); | ||||
|             return errorHandling(next, serverError); | ||||
|         }); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| const path                           = require('path'); | ||||
| const { validationResult }           = require('express-validator'); | ||||
| const bcrypt                         = require('bcryptjs'); | ||||
| const jwt                            = require('jsonwebtoken'); | ||||
| @@ -14,6 +15,55 @@ const Functions                      = require('../models/functions'); | ||||
| const Categories                     = require('../models/categories'); | ||||
| const Comments                       = require('../models/comments'); | ||||
|  | ||||
| async function handleEditUser(res, { name, email, biography, isPublicEmail }, userId, logoName) { | ||||
|     const user = await Users.findOne({ where: { id: userId } }); | ||||
|     user.name = name; | ||||
|     user.email = email; | ||||
|     user.biography = biography; | ||||
|     user.isPublicEmail = isPublicEmail; | ||||
|     if (logoName != undefined) { | ||||
|         user.logo = `/images/users/${logoName}`; | ||||
|     } | ||||
|     await user.save(); | ||||
|     return res.status(200).json({ message: "Le profil a bien été modifié!" }); | ||||
| } | ||||
|  | ||||
| exports.putUser = (req, res, next) => { | ||||
|     const { name, email, biography, isPublicEmail } = req.body; | ||||
|     const logo = req.files.logo; | ||||
|     const errors = validationResult(req); | ||||
|     if (!errors.isEmpty()) { | ||||
|         return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 }); | ||||
|     } | ||||
|     if (logo != undefined) { | ||||
|         if (!logo || logo.truncated && ( | ||||
|             logo.mimetype !== 'image/png' ||  | ||||
|             logo.mimetype !== 'image/jpg' ||  | ||||
|             logo.mimetype !== 'image/jpeg' || | ||||
|             logo.mimetype !== 'image/gif' | ||||
|         )) { | ||||
|             return errorHandling(next, { message:"Le profil doit avoir une image valide.", statusCode: 400 }); | ||||
|         } | ||||
|         const logoName = name + uuid.v4() + logo.name; | ||||
|         logo.mv(path.join(__dirname, '..', 'assets', 'images', 'users') + '/' + logoName, async (error) => { | ||||
|             if (error) return errorHandling(next, serverError); | ||||
|             try { | ||||
|                 return handleEditUser(res, { name, email, biography, isPublicEmail }, req.userId, logoName); | ||||
|             } catch (error) { | ||||
|                 console.log(error); | ||||
|                 return errorHandling(next, serverError); | ||||
|             } | ||||
|         }); | ||||
|     } else { | ||||
|         try { | ||||
|             return handleEditUser(res, { name, email, biography, isPublicEmail }, req.userId, null); | ||||
|         } catch (error) { | ||||
|             console.log(error); | ||||
|             return errorHandling(next, serverError); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| exports.register = async (req, res, next) => { | ||||
|     const { name, email, password } = req.body; | ||||
|     const errors = validationResult(req); | ||||
| @@ -33,7 +83,7 @@ exports.register = async (req, res, next) => { | ||||
|         return res.status(201).json({ result: "Vous y êtes presque, veuillez vérifier vos emails pour confirmer l'inscription." }); | ||||
|     } catch (error) { | ||||
|         console.log(error); | ||||
|         errorHandling(next, serverError); | ||||
|         return errorHandling(next, serverError); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -57,11 +107,11 @@ exports.login = async (req, res, next) => { | ||||
|         } | ||||
|         const token = jwt.sign({  | ||||
|             email: user.email, userId: user.id | ||||
|         }, JWT_SECRET, { expiresIn: '1h' }); | ||||
|         }, JWT_SECRET, { expiresIn: '3h' }); | ||||
|         return res.status(200).json({ token, id: user.id, name: user.name, email: user.email, biography: user.biography, logo: user.logo, isPublicEmail: user.isPublicEmail, isAdmin: user.isAdmin, createdAt: user.createdAt }); | ||||
|     } catch (error) { | ||||
|         console.log(error); | ||||
|         errorHandling(next, serverError); | ||||
|         return errorHandling(next, serverError); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -81,7 +131,7 @@ exports.confirmEmail = async (req, res, next) => { | ||||
|         return res.redirect(`${FRONT_END_HOST}/login?isConfirmed=true`); | ||||
|     } catch (error) { | ||||
|         console.log(error); | ||||
|         errorHandling(next, serverError); | ||||
|         return errorHandling(next, serverError); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -109,7 +159,7 @@ exports.resetPassword = async (req, res, next) => { | ||||
|         return res.status(200).json({ result: "Demande de réinitialisation du mot de passe réussi, veuillez vérifier vos emails!" }); | ||||
|     } catch (error) { | ||||
|         console.log(error); | ||||
|         errorHandling(next, serverError); | ||||
|         return errorHandling(next, serverError); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -132,7 +182,7 @@ exports.newPassword = async (req, res, next) => { | ||||
|         return res.status(200).json({ result: "Le mot de passe a bien été modifié!" }); | ||||
|     } catch (error) { | ||||
|         console.log(error); | ||||
|         errorHandling(next, serverError); | ||||
|         return errorHandling(next, serverError); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -156,10 +206,12 @@ exports.getUserInfo = async (req, res, next) => { | ||||
|         }); | ||||
|         const favoritesArray = favorites.map((favorite) => favorite.function); | ||||
|         const comments = await Comments.findAll({ | ||||
|             limit: 10, | ||||
|             where: { userId: user.id }, | ||||
|             include: [ | ||||
|                 { model: Functions, attributes: { exclude: ["updatedAt", "utilizationForm", "article", "isOnline"] } } | ||||
|             ] | ||||
|             ], | ||||
|             order: [['createdAt', 'DESC']] | ||||
|         }); | ||||
|         const commentsArray = comments.map((commentObject) => { | ||||
|             return { | ||||
| @@ -182,6 +234,6 @@ exports.getUserInfo = async (req, res, next) => { | ||||
|         return res.status(200).json(userObject); | ||||
|     } catch (error) { | ||||
|         console.log(error); | ||||
|         errorHandling(next, serverError); | ||||
|         return errorHandling(next, serverError); | ||||
|     } | ||||
| } | ||||
| @@ -11,68 +11,66 @@ const AdminRouter = Router(); | ||||
|  | ||||
| // Permet de créé une fonction | ||||
| AdminRouter.post('/functions', isAuth, isAdmin,  | ||||
|     fileUpload({  | ||||
|         useTempFiles: true,  | ||||
|         safeFileNames: true, | ||||
|         preserveExtension: Number, | ||||
|         limits: { fileSize: 5 * 1024 * 1024 }, // 5mb, | ||||
|         parseNested: true | ||||
|     }), | ||||
|     [ | ||||
|         body('title') | ||||
|             .not() | ||||
|             .isEmpty() | ||||
|             .withMessage("La fonction doit avoir un titre.") | ||||
|             .isLength({ max: 100 }) | ||||
|             .withMessage("Le titre est trop long."), | ||||
|         body('slug') | ||||
|             .not() | ||||
|             .isEmpty() | ||||
|             .withMessage("La fonction doit avoir un slug.") | ||||
|             .isLength({ max: 100 }) | ||||
|             .withMessage("Le slug est trop long.") | ||||
|             .custom((async (slug) => { | ||||
|                 try { | ||||
|                     const FunctionSlug = await Functions.findOne({ where: { slug } }); | ||||
|                     if (FunctionSlug) { | ||||
|                         return Promise.reject("Le slug existe déjà..."); | ||||
|                     } | ||||
|                 } catch (error) { | ||||
|                     console.log(error); | ||||
| fileUpload({  | ||||
|     useTempFiles: true,  | ||||
|     safeFileNames: true, | ||||
|     preserveExtension: Number, | ||||
|     limits: { fileSize: 5 * 1024 * 1024 }, // 5mb, | ||||
|     parseNested: true | ||||
| }), | ||||
| [ | ||||
|     body('title') | ||||
|         .not() | ||||
|         .isEmpty() | ||||
|         .withMessage("La fonction doit avoir un titre.") | ||||
|         .isLength({ max: 100 }) | ||||
|         .withMessage("Le titre est trop long."), | ||||
|     body('slug') | ||||
|         .not() | ||||
|         .isEmpty() | ||||
|         .withMessage("La fonction doit avoir un slug.") | ||||
|         .isLength({ max: 100 }) | ||||
|         .withMessage("Le slug est trop long.") | ||||
|         .custom((async (slug) => { | ||||
|             try { | ||||
|                 const FunctionSlug = await Functions.findOne({ where: { slug } }); | ||||
|                 if (FunctionSlug) { | ||||
|                     return Promise.reject("Le slug existe déjà..."); | ||||
|                 } | ||||
|                 return true; | ||||
|             })), | ||||
|         body('description') | ||||
|             .not() | ||||
|             .isEmpty() | ||||
|             .withMessage("La fonction doit avoir une description.") | ||||
|             .isLength({ max: 255 }) | ||||
|             .withMessage("La description est trop longue."), | ||||
|         body('categorieId') | ||||
|             .not() | ||||
|             .isEmpty() | ||||
|             .withMessage("La fonction doit avoir une catégorie.") | ||||
|             .custom(async (categorieId) => { | ||||
|                 try { | ||||
|                     const categorieFound = await Categories.findOne({ where: { id: categorieId } }); | ||||
|                     if (!categorieFound) { | ||||
|                         return Promise.reject("La catégorie n'existe pas!"); | ||||
|                     } | ||||
|                 } catch (error) { | ||||
|                     console.log(error); | ||||
|             } catch (error) { | ||||
|                 console.log(error); | ||||
|             } | ||||
|             return true; | ||||
|         })), | ||||
|     body('description') | ||||
|         .not() | ||||
|         .isEmpty() | ||||
|         .withMessage("La fonction doit avoir une description.") | ||||
|         .isLength({ max: 255 }) | ||||
|         .withMessage("La description est trop longue."), | ||||
|     body('categorieId') | ||||
|         .not() | ||||
|         .isEmpty() | ||||
|         .withMessage("La fonction doit avoir une catégorie.") | ||||
|         .custom(async (categorieId) => { | ||||
|             try { | ||||
|                 const categorieFound = await Categories.findOne({ where: { id: categorieId } }); | ||||
|                 if (!categorieFound) { | ||||
|                     return Promise.reject("La catégorie n'existe pas!"); | ||||
|                 } | ||||
|                 return true; | ||||
|             }), | ||||
|         body('type') | ||||
|             .custom((type) => { | ||||
|                 if (!(type === 'article' || type === 'form' || type === 'page')) { | ||||
|                     return Promise.reject('Le type de la fonction peut être : article, form ou page.'); | ||||
|                 } | ||||
|                 return true; | ||||
|             }) | ||||
|     ],  | ||||
|     adminController.postFunction | ||||
| ); | ||||
|             } catch (error) { | ||||
|                 console.log(error); | ||||
|             } | ||||
|             return true; | ||||
|         }), | ||||
|     body('type') | ||||
|         .custom((type) => { | ||||
|             if (!(type === 'article' || type === 'form' || type === 'page')) { | ||||
|                 return Promise.reject('Le type de la fonction peut être : article, form ou page.'); | ||||
|             } | ||||
|             return true; | ||||
|         }) | ||||
| ], adminController.postFunction); | ||||
|  | ||||
| // Supprime une fonction avec son id | ||||
| AdminRouter.delete('/functions/:id', isAuth, isAdmin, adminController.deleteFunction); | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| const { Router }         = require('express'); | ||||
| const { body }           = require('express-validator'); | ||||
| const fileUpload         = require('express-fileupload'); | ||||
| const usersController    = require('../controllers/users'); | ||||
| const { requiredFields } = require('../assets/config/errors'); | ||||
| const Users              = require('../models/users'); | ||||
| const isAuth             = require('../middlewares/isAuth'); | ||||
|  | ||||
| const UsersRouter = Router(); | ||||
|  | ||||
| @@ -21,6 +23,59 @@ UsersRouter.post('/login', [ | ||||
| // Récupère les informations public d'un profil | ||||
| UsersRouter.get('/:name', usersController.getUserInfo); | ||||
|  | ||||
| // Permet de modifier son profil | ||||
| UsersRouter.put('/', isAuth,  | ||||
| fileUpload({  | ||||
|     useTempFiles: true,  | ||||
|     safeFileNames: true, | ||||
|     preserveExtension: Number, | ||||
|     limits: { fileSize: 5 * 1024 * 1024 }, // 5mb, | ||||
|     parseNested: true | ||||
| }), | ||||
| [ | ||||
|     body('email') | ||||
|         .isEmail() | ||||
|         .withMessage("Veuillez rentré une adresse mail valide.") | ||||
|         .custom((async (email) => { | ||||
|             try { | ||||
|                 const user = await Users.findOne({ where: { email } }); | ||||
|                 if (user && user.email !== email) { | ||||
|                     return Promise.reject("L'adresse email existe déjà..."); | ||||
|                 } | ||||
|             } catch (error) { | ||||
|                 return console.log(error); | ||||
|             } | ||||
|             return true; | ||||
|         })) | ||||
|         .normalizeEmail(), | ||||
|     body('name') | ||||
|         .trim() | ||||
|         .not() | ||||
|         .isEmpty() | ||||
|         .withMessage("Vous devez avoir un nom (ou pseudo).") | ||||
|         .isAlphanumeric() | ||||
|         .withMessage("Votre nom ne peut contenir que des lettres ou/et des nombres.") | ||||
|         .isLength({ max: 30 }) | ||||
|         .withMessage("Votre nom est trop long") | ||||
|         .custom(async (name) => { | ||||
|             try { | ||||
|                 const user = await Users.findOne({ where: { name } }); | ||||
|                 if (user && user.name !== name) { | ||||
|                     return Promise.reject("Le nom existe déjà..."); | ||||
|                 } | ||||
|             } catch (error) { | ||||
|                 console.log(error); | ||||
|             } | ||||
|             return true; | ||||
|         }), | ||||
|     body('isPublicEmail') | ||||
|         .isBoolean() | ||||
|         .withMessage("L'adresse email peut être public ou privé, rien d'autre."), | ||||
|     body('biography') | ||||
|         .trim() | ||||
|         .escape() | ||||
| ], usersController.putUser); | ||||
|  | ||||
| // Permet de s'inscrire | ||||
| UsersRouter.post('/register', [ | ||||
|     body('email') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user