🎨 standardJS all files

This commit is contained in:
divlo
2020-08-03 14:14:45 +02:00
parent dc962c9120
commit 4be7a46a10
85 changed files with 3595 additions and 2383 deletions

View File

@ -15,7 +15,12 @@ const { EMAIL_INFO, FRONT_END_HOST } = require('../assets/config/config')
const transporter = require('../assets/config/transporter')
const { emailQuoteTemplate } = require('../assets/config/emails')
const handleEditFunction = async (res, resultFunction, { title, slug, description, type, categorieId, isOnline }, imageName = false) => {
const handleEditFunction = async (
res,
resultFunction,
{ title, slug, description, type, categorieId, isOnline },
imageName = false
) => {
resultFunction.title = title
resultFunction.slug = slug
resultFunction.description = description
@ -32,23 +37,41 @@ const handleEditFunction = async (res, resultFunction, { title, slug, descriptio
exports.getFunctions = async (req, res, next) => {
const categoryId = helperQueryNumber(req.query.categoryId, 0)
let search = req.query.search
try { search = search.toLowerCase() } catch {};
try {
search = search.toLowerCase()
} catch {}
const options = {
where: {
// Trie par catégorie
...(categoryId !== 0) && { categorieId: categoryId },
...(categoryId !== 0 && { categorieId: categoryId }),
// Recherche
...(search != null) && {
...(search != null && {
[Sequelize.Op.or]: [
{ title: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('title')), 'LIKE', `%${search}%`) },
{ slug: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('slug')), 'LIKE', `%${search}%`) },
{ description: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('description')), 'LIKE', `%${search}%`) }
{
title: Sequelize.where(
Sequelize.fn('LOWER', Sequelize.col('title')),
'LIKE',
`%${search}%`
)
},
{
slug: Sequelize.where(
Sequelize.fn('LOWER', Sequelize.col('slug')),
'LIKE',
`%${search}%`
)
},
{
description: Sequelize.where(
Sequelize.fn('LOWER', Sequelize.col('description')),
'LIKE',
`%${search}%`
)
}
]
}
})
},
include: [
{ model: Categories, attributes: ['name', 'color'] }
],
include: [{ model: Categories, attributes: ['name', 'color'] }],
attributes: {
exclude: ['updatedAt', 'utilizationForm', 'article', 'isOnline']
},
@ -61,18 +84,21 @@ exports.getFunctionBySlug = (req, res, next) => {
const { slug } = req.params
Functions.findOne({
where: { slug },
include: [
{ model: Categories, attributes: ['name', 'color'] }
]
include: [{ model: Categories, attributes: ['name', 'color'] }]
})
.then((result) => {
.then(result => {
if (!result) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
try { result.utilizationForm = JSON.parse(result.utilizationForm) } catch {}
try {
result.utilizationForm = JSON.parse(result.utilizationForm)
} catch {}
return res.status(200).json(result)
})
.catch((error) => {
.catch(error => {
console.log(error)
return errorHandling(next, serverError)
})
@ -83,28 +109,49 @@ exports.postFunction = (req, res, next) => {
const image = req.files.image
const errors = validationResult(req)
if (!errors.isEmpty()) {
return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 })
return errorHandling(next, {
message: errors.array()[0].msg,
statusCode: 400
})
}
if ((!image || image.truncated) && (
image.mimetype !== 'image/png' ||
image.mimetype !== 'image/jpg' ||
image.mimetype !== 'image/jpeg'
)) {
return errorHandling(next, { message: 'La fonction doit avoir une image valide.', statusCode: 400 })
if (
(!image || image.truncated) &&
(image.mimetype !== 'image/png' ||
image.mimetype !== 'image/jpg' ||
image.mimetype !== 'image/jpeg')
) {
return errorHandling(next, {
message: 'La fonction doit avoir une image valide.',
statusCode: 400
})
}
const splitedImageName = image.name.split('.')
if (splitedImageName.length !== 2) return errorHandling(next, serverError)
const imageName = slug + '.' + splitedImageName[1]
image.mv(path.join(__dirname, '..', 'assets', 'images', 'functions') + '/' + imageName, async (error) => {
if (error) return errorHandling(next, serverError)
try {
const result = await Functions.create({ title, slug, description, type, categorieId, image: `/images/functions/${imageName}` })
return res.status(201).json({ message: 'La fonction a été correctement ajouté!', result })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
image.mv(
path.join(__dirname, '..', 'assets', 'images', 'functions') +
'/' +
imageName,
async error => {
if (error) return errorHandling(next, serverError)
try {
const result = await Functions.create({
title,
slug,
description,
type,
categorieId,
image: `/images/functions/${imageName}`
})
return res
.status(201)
.json({ message: 'La fonction a été correctement ajouté!', result })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
}
}
})
)
}
exports.putFunction = async (req, res, next) => {
@ -113,43 +160,74 @@ exports.putFunction = async (req, res, next) => {
const image = req.files.image
const errors = validationResult(req)
if (!errors.isEmpty()) {
return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 })
return errorHandling(next, {
message: errors.array()[0].msg,
statusCode: 400
})
}
try {
// Vérifie si la fonction existe
const resultFunction = await Functions.findOne({ where: { id } })
if (!resultFunction) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
// Vérifie si le slug existe déjà
const FunctionSlug = await Functions.findOne({ where: { slug } })
if (!FunctionSlug && FunctionSlug.id !== resultFunction.id) {
return errorHandling(next, { message: 'Le slug existe déjà...', statusCode: 404 })
return errorHandling(next, {
message: 'Le slug existe déjà...',
statusCode: 404
})
}
// Sauvegarde de la fonction
if (image != null) {
if (image.truncated && (
image.mimetype !== 'image/png' ||
image.mimetype !== 'image/jpg' ||
image.mimetype !== 'image/jpeg'
)) {
return errorHandling(next, { message: 'La fonction doit avoir une image valide.', statusCode: 400 })
if (
image.truncated &&
(image.mimetype !== 'image/png' ||
image.mimetype !== 'image/jpg' ||
image.mimetype !== 'image/jpeg')
) {
return errorHandling(next, {
message: 'La fonction doit avoir une image valide.',
statusCode: 400
})
}
const splitedImageName = image.name.split('.')
if (splitedImageName.length !== 2) return errorHandling(next, serverError)
const imageName = slug + '.' + splitedImageName[1]
// Supprime les anciennes images
const functionPath = path.join(__dirname, '..', 'assets', 'images', 'functions')
const functionPath = path.join(
__dirname,
'..',
'assets',
'images',
'functions'
)
deleteFilesNameStartWith(slug, functionPath, () => {
image.mv(path.join(functionPath, imageName), async (error) => {
image.mv(path.join(functionPath, imageName), async error => {
if (error) return errorHandling(next, serverError)
return await handleEditFunction(res, resultFunction, { title, slug, description, type, categorieId, isOnline }, imageName)
return await handleEditFunction(
res,
resultFunction,
{ title, slug, description, type, categorieId, isOnline },
imageName
)
})
})
} else {
return await handleEditFunction(res, resultFunction, { title, slug, description, type, categorieId, isOnline })
return await handleEditFunction(res, resultFunction, {
title,
slug,
description,
type,
categorieId,
isOnline
})
}
} catch (error) {
console.log(error)
@ -165,7 +243,10 @@ exports.putFunctionArticle = async (req, res, next) => {
// Vérifie si la fonction existe
const resultFunction = await Functions.findOne({ where: { id } })
if (!resultFunction) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
resultFunction.article = article
const result = await resultFunction.save()
@ -184,7 +265,10 @@ exports.putFunctionForm = async (req, res, next) => {
// Vérifie si la fonction existe
const resultFunction = await Functions.findOne({ where: { id } })
if (!resultFunction) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
resultFunction.utilizationForm = JSON.stringify(form)
const result = await resultFunction.save()
@ -200,14 +284,19 @@ exports.deleteFunction = async (req, res, next) => {
try {
const result = await Functions.findOne({ where: { id } })
if (!result) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
if (result.image !== '/images/functions/default.png') {
const filePath = path.join(__dirname, '..', 'assets', result.image)
fs.unlinkSync(filePath) // supprime le fichier
}
await result.destroy()
res.status(200).json({ message: 'La fonction a été correctement supprimé!' })
res
.status(200)
.json({ message: 'La fonction a été correctement supprimé!' })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -217,11 +306,15 @@ exports.deleteFunction = async (req, res, next) => {
exports.postCategory = async (req, res, next) => {
const { name, color } = req.body
if (!(name && color)) {
return errorHandling(next, { message: 'La catégorie doit avoir un nom et une couleur.' })
return errorHandling(next, {
message: 'La catégorie doit avoir un nom et une couleur.'
})
}
try {
const result = await Categories.create({ name, color })
return res.status(201).json({ message: 'La catégorie a bien été crée!', result })
return res
.status(201)
.json({ message: 'La catégorie a bien été crée!', result })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -232,7 +325,9 @@ exports.putCategory = async (req, res, next) => {
const { name, color } = req.body
const { id } = req.params
if (!(name && color && id)) {
return errorHandling(next, { message: 'La catégorie doit avoir un nom, une couleur et un id.' })
return errorHandling(next, {
message: 'La catégorie doit avoir un nom, une couleur et un id.'
})
}
try {
const category = await Categories.findOne({ where: { id } })
@ -242,7 +337,9 @@ exports.putCategory = async (req, res, next) => {
category.name = name
category.color = color
const result = await category.save()
return res.status(200).json({ message: 'La catégorie a bien été modifiée!', result })
return res
.status(200)
.json({ message: 'La catégorie a bien été modifiée!', result })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -257,7 +354,9 @@ exports.deleteCategory = async (req, res, next) => {
return errorHandling(next, { message: "La catégorie n'existe pas." })
}
await category.destroy()
return res.status(200).json({ message: 'La catégorie a bien été supprimée!' })
return res
.status(200)
.json({ message: 'La catégorie a bien été supprimée!' })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -269,9 +368,7 @@ exports.getQuotes = async (req, res, next) => {
where: {
isValidated: 0
},
include: [
{ model: Users, attributes: ['name', 'logo'] }
],
include: [{ model: Users, attributes: ['name', 'logo'] }],
order: [['createdAt', 'DESC']]
}
return await getPagesHelper({ req, res, next }, Quotes, options)
@ -282,19 +379,23 @@ exports.putQuote = async (req, res, next) => {
const { isValid } = req.body
try {
if (typeof isValid !== 'boolean') {
return errorHandling(next, { message: 'isValid doit être un booléen.', statusCode: 400 })
return errorHandling(next, {
message: 'isValid doit être un booléen.',
statusCode: 400
})
}
const quote = await Quotes.findOne({
where: {
id,
isValidated: 0
},
include: [
{ model: Users, attributes: ['name', 'email'] }
]
include: [{ model: Users, attributes: ['name', 'email'] }]
})
if (!quote) {
return errorHandling(next, { message: "La citation n'existe pas (ou est déjà validé).", statusCode: 404 })
return errorHandling(next, {
message: "La citation n'existe pas (ou est déjà validé).",
statusCode: 404
})
}
await transporter.sendMail({
@ -307,10 +408,14 @@ exports.putQuote = async (req, res, next) => {
if (isValid) {
quote.isValidated = true
await quote.save()
return res.status(200).json({ message: 'La citation a bien été validée!' })
return res
.status(200)
.json({ message: 'La citation a bien été validée!' })
} else {
await quote.destroy()
return res.status(200).json({ imessage: 'La citation a bien été supprimée!' })
return res
.status(200)
.json({ imessage: 'La citation a bien été supprimée!' })
}
} catch (error) {
console.log(error)

View File

@ -4,10 +4,10 @@ const { serverError } = require('../assets/config/errors')
exports.getCategories = (_req, res, next) => {
Categories.findAll()
.then((result) => {
.then(result => {
res.status(200).json(result)
})
.catch((error) => {
.catch(error => {
console.log(error)
return errorHandling(next, serverError)
})

View File

@ -9,9 +9,7 @@ exports.getCommentsByFunctionId = async (req, res, next) => {
const { functionId } = req.params
const options = {
where: { functionId },
include: [
{ model: Users, attributes: ['name', 'logo'] }
],
include: [{ model: Users, attributes: ['name', 'logo'] }],
order: [['createdAt', 'DESC']]
}
return await getPagesHelper({ req, res, next }, Comments, options)
@ -21,14 +19,26 @@ exports.postCommentsByFunctionId = async (req, res, next) => {
const { functionId } = req.params
const { message } = req.body
try {
const resultFunction = await Functions.findOne({ where: { id: functionId } })
const resultFunction = await Functions.findOne({
where: { id: functionId }
})
if (!resultFunction) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
if (!message) {
return errorHandling(next, { message: 'Vous ne pouvez pas poster de commentaire vide.', statusCode: 400 })
return errorHandling(next, {
message: 'Vous ne pouvez pas poster de commentaire vide.',
statusCode: 400
})
}
const comment = await Comments.create({ message, userId: req.userId, functionId })
const comment = await Comments.create({
message,
userId: req.userId,
functionId
})
return res.status(201).json(comment)
} catch (error) {
console.log(error)
@ -39,12 +49,19 @@ exports.postCommentsByFunctionId = async (req, res, next) => {
exports.deleteCommentById = async (req, res, next) => {
const { commentId } = req.params
try {
const comment = await Comments.findOne({ where: { userId: req.userId, id: parseInt(commentId) } })
const comment = await Comments.findOne({
where: { userId: req.userId, id: parseInt(commentId) }
})
if (!comment) {
return errorHandling(next, { message: "Le commentaire n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "Le commentaire n'existe pas.",
statusCode: 404
})
}
await comment.destroy()
return res.status(200).json({ message: 'Le commentaire a bien été supprimé.' })
return res
.status(200)
.json({ message: 'Le commentaire a bien été supprimé.' })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -55,16 +72,26 @@ exports.putCommentsById = async (req, res, next) => {
const { commentId } = req.params
const { message } = req.body
if (!message) {
return errorHandling(next, { message: 'Vous ne pouvez pas poster de commentaire vide.', statusCode: 400 })
return errorHandling(next, {
message: 'Vous ne pouvez pas poster de commentaire vide.',
statusCode: 400
})
}
try {
const comment = await Comments.findOne({ where: { userId: req.userId, id: parseInt(commentId) } })
const comment = await Comments.findOne({
where: { userId: req.userId, id: parseInt(commentId) }
})
if (!comment) {
return errorHandling(next, { message: "Le commentaire n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "Le commentaire n'existe pas.",
statusCode: 404
})
}
comment.message = message
await comment.save()
return res.status(200).json({ message: 'Le commentaire a bien été modifié.' })
return res
.status(200)
.json({ message: 'Le commentaire a bien été modifié.' })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)

View File

@ -27,9 +27,14 @@ exports.postFavoriteByFunctionId = async (req, res, next) => {
const { functionId } = req.params
const { userId } = req
try {
const resultFunction = await Functions.findOne({ where: { id: functionId } })
const resultFunction = await Functions.findOne({
where: { id: functionId }
})
if (!resultFunction) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
const favorite = await Favorites.findOne({
where: {
@ -41,7 +46,10 @@ exports.postFavoriteByFunctionId = async (req, res, next) => {
await Favorites.create({ userId, functionId })
return res.status(201).json({ result: 'Le favoris a bien été ajouté!' })
}
return errorHandling(next, { message: 'La fonction est déjà en favoris.', statusCode: 400 })
return errorHandling(next, {
message: 'La fonction est déjà en favoris.',
statusCode: 400
})
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -52,9 +60,14 @@ exports.deleteFavoriteByFunctionId = async (req, res, next) => {
const { functionId } = req.params
const { userId } = req
try {
const resultFunction = await Functions.findOne({ where: { id: functionId } })
const resultFunction = await Functions.findOne({
where: { id: functionId }
})
if (!resultFunction) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
const favorite = await Favorites.findOne({
where: {
@ -63,10 +76,15 @@ exports.deleteFavoriteByFunctionId = async (req, res, next) => {
}
})
if (!favorite) {
return errorHandling(next, { message: "Le fonction n'est pas en favoris.", statusCode: 400 })
return errorHandling(next, {
message: "Le fonction n'est pas en favoris.",
statusCode: 400
})
}
await favorite.destroy()
return res.status(200).json({ message: 'Le fonction a bien été supprimé des favoris.' })
return res
.status(200)
.json({ message: 'Le fonction a bien été supprimé des favoris.' })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)

View File

@ -10,24 +10,42 @@ const Sequelize = require('sequelize')
exports.getFunctions = async (req, res, next) => {
const categoryId = helperQueryNumber(req.query.categoryId, 0)
let { search } = req.query
try { search = search.toLowerCase() } catch {};
try {
search = search.toLowerCase()
} catch {}
const options = {
where: {
isOnline: 1,
// Trie par catégorie
...(categoryId !== 0) && { categorieId: categoryId },
...(categoryId !== 0 && { categorieId: categoryId }),
// Recherche
...(search != null) && {
...(search != null && {
[Sequelize.Op.or]: [
{ title: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('title')), 'LIKE', `%${search}%`) },
{ slug: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('slug')), 'LIKE', `%${search}%`) },
{ description: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('description')), 'LIKE', `%${search}%`) }
{
title: Sequelize.where(
Sequelize.fn('LOWER', Sequelize.col('title')),
'LIKE',
`%${search}%`
)
},
{
slug: Sequelize.where(
Sequelize.fn('LOWER', Sequelize.col('slug')),
'LIKE',
`%${search}%`
)
},
{
description: Sequelize.where(
Sequelize.fn('LOWER', Sequelize.col('description')),
'LIKE',
`%${search}%`
)
}
]
}
})
},
include: [
{ model: Categories, attributes: ['name', 'color'] }
],
include: [{ model: Categories, attributes: ['name', 'color'] }],
attributes: {
exclude: ['updatedAt', 'utilizationForm', 'article', 'isOnline']
},
@ -43,18 +61,21 @@ exports.getFunctionBySlug = (req, res, next) => {
attributes: {
exclude: ['updatedAt', 'isOnline']
},
include: [
{ model: Categories, attributes: ['name', 'color'] }
]
include: [{ model: Categories, attributes: ['name', 'color'] }]
})
.then((result) => {
.then(result => {
if (!result) {
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}
try { result.utilizationForm = JSON.parse(result.utilizationForm) } catch {}
try {
result.utilizationForm = JSON.parse(result.utilizationForm)
} catch {}
return res.status(200).json(result)
})
.catch((error) => {
.catch(error => {
console.log(error)
return errorHandling(next, serverError)
})
@ -65,5 +86,8 @@ exports.executeFunctionBySlug = (req, res, next) => {
if (functionOutput !== undefined) {
return functionOutput({ res, next }, req.body)
}
return errorHandling(next, { message: "La fonction n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "La fonction n'existe pas.",
statusCode: 404
})
}

View File

@ -9,9 +9,7 @@ exports.getQuotes = async (req, res, next) => {
where: {
isValidated: 1
},
include: [
{ model: Users, attributes: ['name', 'logo'] }
],
include: [{ model: Users, attributes: ['name', 'logo'] }],
attributes: {
exclude: ['isValidated']
},
@ -27,10 +25,15 @@ exports.postQuote = (req, res, next) => {
return errorHandling(next, requiredFields)
}
Quotes.create({ quote, author, userId: req.userId })
.then((_result) => {
return res.status(200).json({ message: "La citation a bien été ajoutée, elle est en attente de confirmation d'un administrateur." })
.then(_result => {
return res
.status(200)
.json({
message:
"La citation a bien été ajoutée, elle est en attente de confirmation d'un administrateur."
})
})
.catch((error) => {
.catch(error => {
console.log(error)
return errorHandling(next, serverError)
})

View File

@ -36,12 +36,20 @@ exports.putTask = async (req, res, next) => {
const { isCompleted } = req.body
try {
if (typeof isCompleted !== 'boolean') {
return errorHandling(next, { message: 'isCompleted doit être un booléen.', statusCode: 400 })
return errorHandling(next, {
message: 'isCompleted doit être un booléen.',
statusCode: 400
})
}
const taskResult = await Tasks.findOne({ where: { id, userId: req.userId } })
const taskResult = await Tasks.findOne({
where: { id, userId: req.userId }
})
if (!taskResult) {
return errorHandling(next, { message: 'La "tâche à faire" n\'existe pas.', statusCode: 404 })
return errorHandling(next, {
message: 'La "tâche à faire" n\'existe pas.',
statusCode: 404
})
}
taskResult.isCompleted = isCompleted
const taskSaved = await taskResult.save()
@ -55,12 +63,19 @@ exports.putTask = async (req, res, next) => {
exports.deleteTask = async (req, res, next) => {
const { id } = req.params
try {
const taskResult = await Tasks.findOne({ where: { id, userId: req.userId } })
const taskResult = await Tasks.findOne({
where: { id, userId: req.userId }
})
if (!taskResult) {
return errorHandling(next, { message: 'La "tâche à faire" n\'existe pas.', statusCode: 404 })
return errorHandling(next, {
message: 'La "tâche à faire" n\'existe pas.',
statusCode: 404
})
}
await taskResult.destroy()
return res.status(200).json({ message: 'La "tâche à faire" a bien été supprimée!' })
return res
.status(200)
.json({ message: 'La "tâche à faire" a bien été supprimée!' })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)

View File

@ -7,7 +7,13 @@ const uuid = require('uuid')
const Sequelize = require('sequelize')
const errorHandling = require('../assets/utils/errorHandling')
const { serverError, generalError } = require('../assets/config/errors')
const { JWT_SECRET, FRONT_END_HOST, EMAIL_INFO, HOST, TOKEN_LIFE } = require('../assets/config/config')
const {
JWT_SECRET,
FRONT_END_HOST,
EMAIL_INFO,
HOST,
TOKEN_LIFE
} = require('../assets/config/config')
const transporter = require('../assets/config/transporter')
const { emailUserTemplate } = require('../assets/config/emails')
const Users = require('../models/users')
@ -19,7 +25,12 @@ const Quotes = require('../models/quotes')
const deleteFilesNameStartWith = require('../assets/utils/deleteFilesNameStartWith')
const getPagesHelper = require('../assets/utils/getPagesHelper')
async function handleEditUser (res, { name, email, biography, isPublicEmail }, userId, logoName) {
async function handleEditUser (
res,
{ name, email, biography, isPublicEmail },
userId,
logoName
) {
const user = await Users.findOne({ where: { id: userId } })
user.name = name
if (user.email !== email) {
@ -31,7 +42,12 @@ async function handleEditUser (res, { name, email, biography, isPublicEmail }, u
from: `"FunctionProject" <${EMAIL_INFO.auth.user}>`,
to: email,
subject: "FunctionProject - Confirmer l'email",
html: emailUserTemplate("Veuillez confirmer l'email", 'Oui, je confirme.', `${HOST}/users/confirm-email/${tempToken}`, 'Si vous avez reçu ce message par erreur, il suffit de le supprimer. Votre email ne serez pas confirmé si vous ne cliquez pas sur le lien de confirmation ci-dessus.')
html: emailUserTemplate(
"Veuillez confirmer l'email",
'Oui, je confirme.',
`${HOST}/users/confirm-email/${tempToken}`,
'Si vous avez reçu ce message par erreur, il suffit de le supprimer. Votre email ne serez pas confirmé si vous ne cliquez pas sur le lien de confirmation ci-dessus.'
)
})
}
if (biography != null) {
@ -42,22 +58,48 @@ async function handleEditUser (res, { name, email, biography, isPublicEmail }, u
user.logo = `/images/users/${logoName}`
}
await user.save()
return res.status(200).json({ id: user.id, name: user.name, email: user.email, biography: user.biography, logo: user.logo, isPublicEmail: user.isPublicEmail, isAdmin: user.isAdmin, createdAt: user.createdAt })
return res
.status(200)
.json({
id: user.id,
name: user.name,
email: user.email,
biography: user.biography,
logo: user.logo,
isPublicEmail: user.isPublicEmail,
isAdmin: user.isAdmin,
createdAt: user.createdAt
})
}
exports.getUsers = async (req, res, next) => {
let { search } = req.query
try { search = search.toLowerCase() } catch {};
try {
search = search.toLowerCase()
} catch {}
const options = {
where: {
isConfirmed: true,
// Recherche
...(search != null) && {
name: Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('name')), 'LIKE', `%${search}%`)
}
...(search != null && {
name: Sequelize.where(
Sequelize.fn('LOWER', Sequelize.col('name')),
'LIKE',
`%${search}%`
)
})
},
attributes: {
exclude: ['updatedAt', 'isAdmin', 'isConfirmed', 'password', 'tempToken', 'tempExpirationToken', 'isPublicEmail', 'email']
exclude: [
'updatedAt',
'isAdmin',
'isConfirmed',
'password',
'tempToken',
'tempExpirationToken',
'isPublicEmail',
'email'
]
},
order: [['createdAt', 'DESC']]
}
@ -69,35 +111,60 @@ exports.putUser = async (req, res, next) => {
const logo = req.files.logo
const errors = validationResult(req)
if (!errors.isEmpty()) {
return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 })
return errorHandling(next, {
message: errors.array()[0].msg,
statusCode: 400
})
}
if (logo != null) {
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 (PNG, JPG, GIF) et moins de 5mo.', statusCode: 400 })
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 (PNG, JPG, GIF) et moins de 5mo.',
statusCode: 400
})
}
const splitedLogoName = logo.name.split('.')
if (splitedLogoName.length !== 2) return errorHandling(next, serverError)
const logoName = name + req.userId + '.' + splitedLogoName[1]
// Supprime les anciens logo
try {
deleteFilesNameStartWith(`${name + req.userId}`, path.join(__dirname, '..', 'assets', 'images', 'users'), async () => {
logo.mv(path.join(__dirname, '..', 'assets', 'images', 'users', logoName), async (error) => {
if (error) return errorHandling(next, serverError)
return await handleEditUser(res, { name, email, biography, isPublicEmail }, req.userId, logoName)
})
})
deleteFilesNameStartWith(
`${name + req.userId}`,
path.join(__dirname, '..', 'assets', 'images', 'users'),
async () => {
logo.mv(
path.join(__dirname, '..', 'assets', 'images', 'users', logoName),
async error => {
if (error) return errorHandling(next, serverError)
return await handleEditUser(
res,
{ name, email, biography, isPublicEmail },
req.userId,
logoName
)
}
)
}
)
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
}
} else {
try {
return await handleEditUser(res, { name, email, biography, isPublicEmail }, req.userId, null)
return await handleEditUser(
res,
{ name, email, biography, isPublicEmail },
req.userId,
null
)
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -109,7 +176,10 @@ exports.register = async (req, res, next) => {
const { name, email, password } = req.body
const errors = validationResult(req)
if (!errors.isEmpty()) {
return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 })
return errorHandling(next, {
message: errors.array()[0].msg,
statusCode: 400
})
}
try {
const hashedPassword = await bcrypt.hash(password, 12)
@ -119,9 +189,19 @@ exports.register = async (req, res, next) => {
from: `"FunctionProject" <${EMAIL_INFO.auth.user}>`,
to: email,
subject: "FunctionProject - Confirmer l'inscription",
html: emailUserTemplate("Veuillez confirmer l'inscription", "Oui, je m'inscris.", `${HOST}/users/confirm-email/${tempToken}`, 'Si vous avez reçu ce message par erreur, il suffit de le supprimer. Vous ne serez pas inscrit si vous ne cliquez pas sur le lien de confirmation ci-dessus.')
html: emailUserTemplate(
"Veuillez confirmer l'inscription",
"Oui, je m'inscris.",
`${HOST}/users/confirm-email/${tempToken}`,
'Si vous avez reçu ce message par erreur, il suffit de le supprimer. Vous ne serez pas inscrit si vous ne cliquez pas sur le lien de confirmation ci-dessus.'
)
})
return res.status(201).json({ result: "Vous y êtes presque, veuillez vérifier vos emails pour confirmer l'inscription." })
return res
.status(201)
.json({
result:
"Vous y êtes presque, veuillez vérifier vos emails pour confirmer l'inscription."
})
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -132,24 +212,55 @@ exports.login = async (req, res, next) => {
const { email, password } = req.body
const errors = validationResult(req)
if (!errors.isEmpty()) {
return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 })
return errorHandling(next, {
message: errors.array()[0].msg,
statusCode: 400
})
}
try {
const user = await Users.findOne({ where: { email } })
if (!user) {
return errorHandling(next, { message: "Le mot de passe ou l'adresse email n'est pas valide.", statusCode: 400 })
return errorHandling(next, {
message: "Le mot de passe ou l'adresse email n'est pas valide.",
statusCode: 400
})
}
const isEqual = await bcrypt.compare(password, user.password)
if (!isEqual) {
return errorHandling(next, { message: "Le mot de passe ou l'adresse email n'est pas valide.", statusCode: 400 })
return errorHandling(next, {
message: "Le mot de passe ou l'adresse email n'est pas valide.",
statusCode: 400
})
}
if (!user.isConfirmed) {
return errorHandling(next, { message: 'Vous devez valider votre adresse email pour votre première connexion.', statusCode: 400 })
return errorHandling(next, {
message:
'Vous devez valider votre adresse email pour votre première connexion.',
statusCode: 400
})
}
const token = jwt.sign({
email: user.email, userId: user.id
}, JWT_SECRET, { expiresIn: TOKEN_LIFE })
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, expiresIn: Math.round(ms(TOKEN_LIFE) / 1000) })
const token = jwt.sign(
{
email: user.email,
userId: user.id
},
JWT_SECRET,
{ expiresIn: TOKEN_LIFE }
)
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,
expiresIn: Math.round(ms(TOKEN_LIFE) / 1000)
})
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -162,9 +273,14 @@ exports.confirmEmail = async (req, res, next) => {
return errorHandling(next, generalError)
}
try {
const user = await Users.findOne({ where: { tempToken, isConfirmed: false } })
const user = await Users.findOne({
where: { tempToken, isConfirmed: false }
})
if (!user) {
return errorHandling(next, { message: "Le token n'est pas valide.", statusCode: 400 })
return errorHandling(next, {
message: "Le token n'est pas valide.",
statusCode: 400
})
}
user.tempToken = null
user.isConfirmed = true
@ -180,12 +296,19 @@ exports.resetPassword = async (req, res, next) => {
const { email } = req.body
const errors = validationResult(req)
if (!errors.isEmpty()) {
return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 })
return errorHandling(next, {
message: errors.array()[0].msg,
statusCode: 400
})
}
try {
const user = await Users.findOne({ where: { email, tempToken: null } })
if (!user) {
return errorHandling(next, { message: "L'adresse email n'existe pas ou une demande est déjà en cours.", statusCode: 400 })
return errorHandling(next, {
message:
"L'adresse email n'existe pas ou une demande est déjà en cours.",
statusCode: 400
})
}
const tempToken = uuid.v4()
user.tempExpirationToken = Date.now() + 3600000 // 1 heure
@ -195,9 +318,19 @@ exports.resetPassword = async (req, res, next) => {
from: `"FunctionProject" <${EMAIL_INFO.auth.user}>`,
to: email,
subject: 'FunctionProject - Réinitialisation du mot de passe',
html: emailUserTemplate('Veuillez confirmer la réinitialisation du mot de passe', 'Oui, je change mon mot de passe.', `${FRONT_END_HOST}/users/newPassword?token=${tempToken}`, 'Si vous avez reçu ce message par erreur, il suffit de le supprimer. Votre mot de passe ne sera pas réinitialiser si vous ne cliquez pas sur le lien ci-dessus. Par ailleurs, pour la sécurité de votre compte, la réinitialisation du mot de passe est disponible pendant un délai de 1 heure, passez ce temps, la réinitialisation ne sera plus valide.')
html: emailUserTemplate(
'Veuillez confirmer la réinitialisation du mot de passe',
'Oui, je change mon mot de passe.',
`${FRONT_END_HOST}/users/newPassword?token=${tempToken}`,
'Si vous avez reçu ce message par erreur, il suffit de le supprimer. Votre mot de passe ne sera pas réinitialiser si vous ne cliquez pas sur le lien ci-dessus. Par ailleurs, pour la sécurité de votre compte, la réinitialisation du mot de passe est disponible pendant un délai de 1 heure, passez ce temps, la réinitialisation ne sera plus valide.'
)
})
return res.status(200).json({ result: 'Demande de réinitialisation du mot de passe réussi, veuillez vérifier vos emails!' })
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)
return errorHandling(next, serverError)
@ -208,19 +341,27 @@ exports.newPassword = async (req, res, next) => {
const { tempToken, password } = req.body
const errors = validationResult(req)
if (!errors.isEmpty()) {
return errorHandling(next, { message: errors.array()[0].msg, statusCode: 400 })
return errorHandling(next, {
message: errors.array()[0].msg,
statusCode: 400
})
}
try {
const user = await Users.findOne({ where: { tempToken } })
if (!user && parseInt(user.tempExpirationToken) < Date.now()) {
return errorHandling(next, { message: "Le token n'est pas valide.", statusCode: 400 })
return errorHandling(next, {
message: "Le token n'est pas valide.",
statusCode: 400
})
}
const hashedPassword = await bcrypt.hash(password, 12)
user.password = hashedPassword
user.tempToken = null
user.tempExpirationToken = null
await user.save()
return res.status(200).json({ result: 'Le mot de passe a bien été modifié!' })
return res
.status(200)
.json({ result: 'Le mot de passe a bien été modifié!' })
} catch (error) {
console.log(error)
return errorHandling(next, serverError)
@ -233,30 +374,51 @@ exports.getUserInfo = async (req, res, next) => {
const user = await Users.findOne({
where: { name, isConfirmed: true },
attributes: {
exclude: ['updatedAt', 'isAdmin', 'isConfirmed', 'password', 'tempToken', 'tempExpirationToken']
exclude: [
'updatedAt',
'isAdmin',
'isConfirmed',
'password',
'tempToken',
'tempExpirationToken'
]
}
})
if (!user) {
return errorHandling(next, { message: "L'utilisateur n'existe pas.", statusCode: 404 })
return errorHandling(next, {
message: "L'utilisateur n'existe pas.",
statusCode: 404
})
}
const favorites = await Favorites.findAll({
where: { userId: user.id },
include: [
{ model: Functions, attributes: { exclude: ['updatedAt', 'utilizationForm', 'article', 'isOnline'] }, include: { model: Categories, attributes: ['name', 'color'] } }
{
model: Functions,
attributes: {
exclude: ['updatedAt', 'utilizationForm', 'article', 'isOnline']
},
include: { model: Categories, attributes: ['name', 'color'] }
}
],
order: [['createdAt', 'DESC']],
limit: 5
})
const favoritesArray = favorites.map((favorite) => favorite.function)
const favoritesArray = favorites.map(favorite => favorite.function)
const comments = await Comments.findAll({
where: { userId: user.id },
include: [
{ model: Functions, attributes: { exclude: ['updatedAt', 'utilizationForm', 'article', 'isOnline'] } }
{
model: Functions,
attributes: {
exclude: ['updatedAt', 'utilizationForm', 'article', 'isOnline']
}
}
],
order: [['createdAt', 'DESC']],
limit: 5
})
const commentsArray = comments.map((commentObject) => {
const commentsArray = comments.map(commentObject => {
return {
id: commentObject.id,
message: commentObject.message,
@ -274,7 +436,7 @@ exports.getUserInfo = async (req, res, next) => {
})
const userObject = {
// Si Public Email
...(user.isPublicEmail) && { email: user.email },
...(user.isPublicEmail && { email: user.email }),
isPublicEmail: user.isPublicEmail,
name: user.name,
biography: user.biography,