2024-01-26 13:38:28 +00:00
|
|
|
'use strict';
|
|
|
|
|
2021-04-12 03:24:17 +00:00
|
|
|
const Joi = require('joi');
|
|
|
|
const { encryptSha1, compareSha1 } = require('iut-encrypt-cemal'); // Importe les fonctions d'encryption
|
|
|
|
const Jwt = require('@hapi/jwt');
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = [
|
|
|
|
{
|
|
|
|
method: 'post',
|
|
|
|
path: '/user',
|
|
|
|
options: {
|
|
|
|
auth: false,
|
|
|
|
tags:['api'],
|
|
|
|
validate: {
|
|
|
|
payload: Joi.object({
|
|
|
|
scope: Joi.string().valid('admin', 'user').example('admin').description('Scope of the user (user or admin)'),
|
|
|
|
firstName: Joi.string().required().min(3).example('John').description('Firstname of the user'),
|
|
|
|
lastName: Joi.string().required().min(3).example('Doe').description('Lastname of the user'),
|
|
|
|
username: Joi.string().required().min(3).example('john_doe').description('Username of the user'),
|
|
|
|
email: Joi.string().email().required().example('john@example.com').description('Email address of the user'),
|
|
|
|
password: Joi.string().required().min(8).example('password123').description('Password of the user')
|
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
handler: async (request, h) => {
|
|
|
|
const { userService } = request.services();
|
|
|
|
const { emailService } = request.services();
|
|
|
|
|
|
|
|
//send welcome email
|
|
|
|
const { email, firstName, lastName } = request.payload;
|
|
|
|
await emailService.sendEmail(
|
|
|
|
email,
|
|
|
|
firstName,
|
|
|
|
lastName,
|
|
|
|
'welcome',
|
|
|
|
'<!DOCTYPE html>\n' +
|
|
|
|
'<html lang="en">\n' +
|
|
|
|
'\n' +
|
|
|
|
'<head>\n' +
|
|
|
|
' <meta charset="UTF-8">\n' +
|
|
|
|
' <meta name="viewport" content="width=device-width, initial-scale=1.0">\n' +
|
|
|
|
' <title>Welcome to Our Application!</title>\n' +
|
|
|
|
' <style>\n' +
|
|
|
|
' body {\n' +
|
|
|
|
' font-family: Arial, sans-serif;\n' +
|
|
|
|
' background-color: #f7f7f7;\n' +
|
|
|
|
' margin: 0;\n' +
|
|
|
|
' padding: 0;\n' +
|
|
|
|
' color: #333;\n' +
|
|
|
|
' }\n' +
|
|
|
|
'\n' +
|
|
|
|
' .container {\n' +
|
|
|
|
' max-width: 600px;\n' +
|
|
|
|
' margin: 50px auto;\n' +
|
|
|
|
' padding: 20px;\n' +
|
|
|
|
' background-color: #fff;\n' +
|
|
|
|
' border-radius: 10px;\n' +
|
|
|
|
' box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n' +
|
|
|
|
' text-align: center;\n' +
|
|
|
|
' }\n' +
|
|
|
|
'\n' +
|
|
|
|
' .header {\n' +
|
|
|
|
' text-align: center;\n' +
|
|
|
|
' margin-bottom: 30px;\n' +
|
|
|
|
' }\n' +
|
|
|
|
'\n' +
|
|
|
|
' .logo {\n' +
|
|
|
|
' width: 100px;\n' +
|
|
|
|
' height: auto;\n' +
|
|
|
|
' }\n' +
|
|
|
|
'\n' +
|
|
|
|
' .content {\n' +
|
|
|
|
' text-align: justify;\n' +
|
|
|
|
' line-height: 1.6;\n' +
|
|
|
|
' margin-bottom: 30px;\n' +
|
|
|
|
' font-size: 16px;\n' +
|
|
|
|
' }\n' +
|
|
|
|
'\n' +
|
|
|
|
' .cta-button {\n' +
|
|
|
|
' display: inline-block;\n' +
|
|
|
|
' padding: 10px 20px;\n' +
|
|
|
|
' background-color: #ff6f61;\n' +
|
|
|
|
' color: #fff;\n' +
|
|
|
|
' text-decoration: none;\n' +
|
|
|
|
' border-radius: 5px;\n' +
|
|
|
|
' margin-top: 30px;\n' +
|
|
|
|
' transition: background-color 0.3s ease;\n' +
|
|
|
|
' font-weight: bold;\n' +
|
|
|
|
' text-align: center;\n' +
|
|
|
|
' }\n' +
|
|
|
|
'\n' +
|
|
|
|
' .footer {\n' +
|
|
|
|
' text-align: center;\n' +
|
|
|
|
' margin-top: 30px;\n' +
|
|
|
|
' font-size: 12px;\n' +
|
|
|
|
' color: #666;\n' +
|
|
|
|
' }\n' +
|
|
|
|
' </style>\n' +
|
|
|
|
'</head>\n' +
|
|
|
|
'\n' +
|
|
|
|
'<body>\n' +
|
|
|
|
'<div class="container">\n' +
|
|
|
|
' <div class="header">\n' +
|
|
|
|
' <h1>Welcome to Our Application!</h1>\n' +
|
|
|
|
' </div>\n' +
|
|
|
|
' <div class="content">\n' +
|
|
|
|
' <p>Hello,</p>\n' +
|
|
|
|
' <p>We are thrilled to have you join our community! Your journey with us begins now, and we can\'t wait to\n' +
|
|
|
|
' share\n' +
|
|
|
|
' all the exciting features and updates we have in store for you.</p>\n' +
|
|
|
|
' <p>To get started, simply log in to your account and explore everything our application has to offer.\n' +
|
|
|
|
' Don\'t hesitate to reach out to our support team if you have any questions or need assistance along the\n' +
|
|
|
|
' way.</p>\n' +
|
|
|
|
' <a href="http://localhost:4000/documentation#/user/postUser" class="cta-button">Log In Now</a>\n' +
|
|
|
|
' <p>Happy exploring!</p>\n' +
|
|
|
|
' </div>\n' +
|
|
|
|
' <div class="footer">\n' +
|
|
|
|
' <p>© 2024 Cemal. All rights reserved.</p>\n' +
|
|
|
|
' </div>\n' +
|
|
|
|
'</div>\n' +
|
|
|
|
'</body>\n' +
|
|
|
|
'\n' +
|
|
|
|
'</html>\n'
|
|
|
|
);
|
|
|
|
|
|
|
|
// Appelle la méthode create du userService en passant les champs nécessaires
|
|
|
|
return await userService.create({
|
|
|
|
scope: request.payload.scope,
|
|
|
|
firstName: request.payload.firstName,
|
|
|
|
lastName: request.payload.lastName,
|
|
|
|
username: request.payload.username,
|
|
|
|
email: request.payload.email,
|
|
|
|
password: request.payload.password
|
|
|
|
});
|
|
|
|
}
|
2024-01-26 14:37:47 +00:00
|
|
|
},
|
2021-04-12 03:24:17 +00:00
|
|
|
{
|
|
|
|
method: 'GET',
|
|
|
|
path: '/users',
|
|
|
|
options: {
|
|
|
|
tags: ['api'],
|
|
|
|
},
|
|
|
|
handler: async (request, h) => {
|
|
|
|
const { User } = request.models();
|
|
|
|
|
|
|
|
// Récupère tous les utilisateurs dans la base de données
|
|
|
|
const users = await User.query();
|
|
|
|
|
|
|
|
return users; // Renvoie tous les utilisateurs
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
method: 'DELETE',
|
|
|
|
path: '/user/{id}',
|
|
|
|
options: {
|
|
|
|
auth: {
|
|
|
|
scope : 'admin'
|
|
|
|
},
|
|
|
|
tags: ['api'],
|
|
|
|
validate: {
|
|
|
|
params: Joi.object({
|
|
|
|
id: Joi.number().integer().positive().required().example(1).description('ID of the user to delete')
|
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
handler: async (request, h) => {
|
|
|
|
const { userService } = request.services();
|
|
|
|
const { id } = request.params;
|
|
|
|
|
|
|
|
// Appelle la méthode delete du userService pour supprimer l'utilisateur par son ID
|
|
|
|
await userService.delete(id);
|
|
|
|
|
|
|
|
// Renvoie une réponse vide lorsque la suppression se déroule correctement
|
|
|
|
return 'deleted';
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
method: 'PATCH',
|
|
|
|
path: '/user/{id}',
|
|
|
|
options: {
|
|
|
|
auth: {
|
|
|
|
strategy: 'jwt',
|
|
|
|
scope : ['admin']
|
|
|
|
},
|
|
|
|
tags: ['api'],
|
|
|
|
validate: {
|
|
|
|
params: Joi.object({
|
|
|
|
id: Joi.number().integer().positive().required().example(1).description('ID of the user to update')
|
|
|
|
}),
|
|
|
|
payload: Joi.object({
|
|
|
|
scope: Joi.string().valid('admin').example('admin').description('New scope of the user'),
|
|
|
|
username: Joi.string().min(3).example('john_doe').description('New username of the user'),
|
|
|
|
firstName: Joi.string().min(3).example('John').description('New firstname of the user'),
|
|
|
|
lastName: Joi.string().min(3).example('Doe').description('New lastname of the user'),
|
|
|
|
email: Joi.string().email().example('john@example.com').description('New email address of the user'),
|
|
|
|
password: Joi.string().min(8).example('password123').description('New password of the user')
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
handler: async (request, h) => {
|
|
|
|
const { userService } = request.services();
|
|
|
|
const { id } = request.params;
|
|
|
|
|
|
|
|
// Appelle la méthode update du userService pour mettre à jour l'utilisateur par son ID
|
|
|
|
return await userService.update(id, request.payload);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
method: 'POST',
|
|
|
|
path: '/user/login',
|
|
|
|
options: {
|
|
|
|
auth: false,
|
|
|
|
tags: ['api'],
|
|
|
|
validate: {
|
|
|
|
payload: Joi.object({
|
|
|
|
email: Joi.string().email().required().example('john@example.com').description('Email address of the user'),
|
|
|
|
password: Joi.string().min(8).required().example('password123').description('Password of the user')
|
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
handler: async (request, h) => {
|
|
|
|
const {User} = request.models();
|
|
|
|
const {email, password} = request.payload;
|
|
|
|
|
|
|
|
// Récupère l'utilisateur par son email depuis la base de données
|
|
|
|
const user = await User.query().findOne({email});
|
|
|
|
|
|
|
|
// Vérifie si l'utilisateur existe et si le mot de passe est valide
|
|
|
|
if (user && compareSha1(password, user.password)) {
|
|
|
|
// Génère un JWT avec les informations de l'utilisateur
|
|
|
|
const token = Jwt.token.generate({
|
|
|
|
aud: 'urn:audience:iut',
|
|
|
|
iss: 'urn:issuer:iut',
|
|
|
|
firstName: user.firstName,
|
|
|
|
lastName: user.lastName,
|
|
|
|
email: user.email,
|
|
|
|
scope: user.scope,
|
|
|
|
}, {
|
|
|
|
key: 'random_string', // Clé secrète pour signer le JWT (devrait être stockée en toute sécurité)
|
|
|
|
algorithm: 'HS512'
|
|
|
|
}, {
|
|
|
|
ttlSec: 14400 // Durée de validité du JWT en secondes (4 heures)
|
|
|
|
});
|
|
|
|
|
|
|
|
// Retourne le JWT généré
|
|
|
|
return {token};
|
|
|
|
} else {
|
|
|
|
// Si le mot de passe n'est pas correct, retourne une réponse 401 Unauthorized
|
|
|
|
return h.response().code(401);
|
|
|
|
}
|
|
|
|
},
|
2024-01-26 13:38:28 +00:00
|
|
|
|
|
|
|
}
|
2021-04-12 03:24:17 +00:00
|
|
|
|
|
|
|
];
|