const express = require('express') const mysql = require("mysql") const dotenv = require('dotenv') const app = express() const path = require("path") const publicDir = path.join(__dirname, './public') const bodyParser = require('body-parser') const functions = require(publicDir + "/functions"); const bcrypt = require("bcrypt") const saltRounds = 10; /* Connexion à la BDD MySQL */ dotenv.config({ path: './.env'}) const db = mysql.createConnection({ host: process.env.DATABASE_HOST, port: process.env.DATABASE_PORT, user: process.env.DATABASE_USER, password: process.env.DATABASE_PASSWORD, database: process.env.DATABASE }) db.connect((error) => { if(error) { console.log(error) } else { console.log("MySQL connected!") } }) app.set('view engine', 'hbs'); app.use(express.static(publicDir)); app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); app.use('/css', express.static(__dirname + '/node_modules/@eonasdan/tempus-dominus/dist/css')); app.use('/js', express.static(__dirname + '/node_modules/@eonasdan/tempus-dominus/dist/js')); app.use(bodyParser.urlencoded({extended: false})); app.use(bodyParser.json()); // ******************************************* Arrivée sur la page d'accueil ******************************************* app.get("/", (req, res) => { let today = functions.getNowDate("yyyymmdd"); // On récupère la liste des sessions actives et pour lesquelles il reste de la place db.query('SELECT ID, topic, DATE_FORMAT(scheduled_on, "%d/%m/%Y") as "date", DATE_FORMAT(scheduled_on, "%Hh%i") as "heure", IF(nb_of_attended-nb_of_participants=0, true, false) as "maxAtteint" FROM session WHERE DATE_FORMAT(scheduled_on, "%Y%m%d") >= ?', [today], async (error, result) => { if(error){ console.log(error); } if (result && result.length == 0) { res.render("login-session", { error: 'Aucune session disponible' }); } else { res.render("login-session", { select: result} ); } }); }); app.get("/index", (req, res) => { res.render("index") }); app.get("/login", (req, res) => { res.render("login") }); app.get("/register", (req, res) => { res.status(404).send('Page Not found'); /* res.render("register", { session: req.query.s, role: req.query.r}) */ }); app.get("/create-session", (req, res) => { res.render("create-session") }); // ******************************************* Création d'un nouveau compte ******************************************* app.post("/auth/register", (req, res) => { const { gender, name, firstname, nickname, title, email, password, password_confirm, session, role } = req.body let requete = ''; if (nickname != '') { requete = "SELECT * FROM user WHERE UPPER(nickname) = '?'".replace("?", nickname.toUpperCase()); } if (email != '') { requete = "SELECT * FROM user WHERE UPPER(email) = '?'".replace("?", email.toUpperCase()); } if (requete.length > 0) { let topic, sessionDate; db.query(requete, async (error, result) => { if(error){ console.log(error) } if( result.length > 0 ) { return res.render('register', { error: 'Adresse email ou pseudo déjà utilisé : modifiez votre saisie ou bien cliquez sur le lien ci-dessus pour vous connecter', session: session, role: role }) } else if(password !== password_confirm) { return res.render('register', { error: 'Vos mots de passe ne correspondent pas', session: session, role: role }) } db.query('SELECT topic, DATE_FORMAT(scheduled_on, "%d/%m/%Y %H:%i") as "date" FROM session WHERE id = ?', [session], (err, result) => { if(error){ console.log(error) } if( result.length > 0 ) { topic = result[0].topic; sessionDate = result[0].date; } }) bcrypt.genSalt(saltRounds, (err, salt) => { bcrypt.hash(password, salt, (err, hash) => { db.query('INSERT INTO user SET?', {gender : (gender != undefined ? gender : ""), firstname: firstname, name: name, title: title, email: email, nickname : nickname, password: hash}, (err, result) => { if(error) { console.log(error) } else { return res.render('login', { session: session, role: role, email: email, nickname: nickname, topic: topic, session_date: sessionDate }) } }) }) }) }) } }) // ******************************************* Connexion sur le compte utilisateur (sans sécurité) ******************************************* app.post("/auth/check-login-no-security", (req, res) => { let newUser; const { nickname, role, session } = req.body; db.query('SELECT ID FROM user WHERE UPPER(nickname)=? AND session=?', [nickname.toUpperCase(), session], (error, result) => { if(error){ console.log(error) } if(result && result.length > 0) { return res.render('login', { error: 'Identifiant déjà utilisé : veuillez en choisir un autre', session: session, role: role }); } else { // On crée l'utilisateur pour traçabilité var newUser = functions.getUuid(); db.query('INSERT INTO user SET?', {id: newUser, nickname : nickname, session: session}, (error, result) => { if(error){ console.log(error); rollback(session, newUser); } if(result && result.affectedRows > 0) { // On trace la connexion de l'utilisateur à la session... db.query('INSERT INTO participation (user, session, role_during_session) VALUES (?,?,?)', [newUser, session, role], function (error, result) { if(error){ console.log(error); rollback(session, newUser);} if(result.affectedRows > 0) { console.log("1 record inserted"); } }); // ... et on incrémente le nb de participants. db.query('UPDATE session SET nb_of_participants = nb_of_participants + 1 WHERE ID=?', [session], function (error, result) { if (error) { console.log(error); rollback(session, newUser); } console.log("1 record updated"); }); } if (role == 'A') { res.redirect(process.env.MASTER_URL); } else { res.redirect(process.env.SLAVE_URL); } }); } }); }); // ******************************************* Connexion sur le compte utilisateur (mode sécurisé) ******************************************* app.post("/auth/check-login", (req, res) => { var userId, passwordStocke; const { email, nickname, password, role, session } = req.body if (email == '' && nickname == '') { return res.render('login', { error: 'Veuillez saisir soit votre pseudo, soit une adresse email', session: session, role: role }) } let requete = ''; if (nickname != '') { requete = "SELECT * FROM user WHERE UPPER(nickname) = '?'".replace("?", nickname.toUpperCase()); } if (email != '') { requete = "SELECT * FROM user WHERE UPPER(email) = '?'".replace("?", email.toUpperCase()); } db.query(requete, async (error, result) => { if(error){ console.log(error) } if( result.length == 0 ) { return res.render('login', { error: 'Utilisateur inconnu : veuillez créer votre compte via le lien ci-dessus', session: session, role: role }) } userId = result[0].ID; bcrypt.compare(password, result[0].password) .then(result => { if (result) { if (result.length == 0) { db.query('INSERT INTO participation (user, session, role_during_session) VALUES (?,?,?)', [userId, session[0], role[0]], function (err, result) { if (err) throw err; console.log("1 record inserted"); }); db.query('UPDATE session SET nb_of_participants = nb_of_participants + 1 WHERE ID=?', session, function (err, result) { if (err) throw err; console.log("1 record updated"); }); } if (role == 'A') { res.redirect('https://slave.thecoredev.fr'); } else { res.redirect('https://slave.thecoredev.fr'); } } else { return res.render('login', { error: 'Mot de passe incorrect : corriger votre saisie', session: session, role: role }) } }) }) }) // ******************************************* Connexion sur la session ******************************************* app.post("/auth/check-session", (req, res) => { const { session, session_password, role } = req.body let listeSessions; let today = functions.getNowDate("yyyymmdd"); db.query('SELECT ID, topic, DATE_FORMAT(scheduled_on, "%d/%m/%Y") as "date", DATE_FORMAT(scheduled_on, "%Hh%i") as "heure", IF(nb_of_attended-nb_of_participants=0, true, false) as "maxAtteint" FROM session WHERE DATE_FORMAT(scheduled_on, "%Y%m%d") >= ?', [today], async (error, result) => { if(error){ console.log(error); } if (result.length == 0) { res.redirect(''); } else { listeSessions = result; } }); db.query('SELECT password, topic, DATE_FORMAT(scheduled_on, "%d/%m/%Y %H:%i") as "date" FROM session WHERE ID = ?', [session], async (error, result) => { if(error){ console.log(error) } if( result.length == 0 ) { return res.render('login-session', { error: 'Session inconnue : veuillez saisir un identifiant de session valide' }) } else { let sessionDate = result[0].date; let sessionTopic = result[0].topic; bcrypt.compare(session_password, result[0].password) .then(result => { if (result) { return res.render('login', {"session": session, "role": role, "topic": sessionTopic, "session_date": sessionDate}) } else { return res.render('login-session', { "error": "Mot de passe incorrect : corriger votre saisie", "select": listeSessions }) } }) .catch(err => { console.log(err); }) } }) }) // ******************************************* Création d'une nouvelle session ******************************************* app.post("/record-session", async (req, res) => { const { topic, attended, password, password_confirm, datetimepicker1Input } = req.body // On traite d'abord les motifs de rejet du formulaire. if (isNaN(attended) || (!isNaN(attended) && attended < 0)) { return res.render('create-session', { error: "Le nombre de participants n'a pas une valeur correcte." }) } if(password !== password_confirm) { return res.render('create-session', { error: 'Vos mots de passe ne correspondent pas' }) } var newSessionId = functions.getUuid(); bcrypt.genSalt(saltRounds, (err, salt) => { bcrypt.hash(password, salt, (err, hash) => { db.query("INSERT INTO session (id, topic, password, nb_of_attended, scheduled_on) VALUES (?,?,?,?,STR_TO_DATE(?,'%d/%m/%Y %H:%i'))", [newSessionId, topic, hash, attended, datetimepicker1Input], (error, result) => { if(error){ console.log(error); } if(result && result.affectedRows > 0) { res.redirect('/'); } }); }); }); }); app.listen(5005, ()=> { console.log("server started on port 5005") })