From 7bafca1dc9863734c0859894f77822652d74d1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20PENHO=C3=8BT?= Date: Wed, 12 Aug 2020 18:51:25 +0200 Subject: [PATCH] Revue processus connexion compte avec mot de passe ou envoi de lien. --- controllers/user.js | 23 ++++++++++++++------ front/public/login.html | 2 +- front/src/connection.js | 47 ++++++++++++++++++----------------------- front/src/subscribe.js | 2 +- lang/fr/user.js | 4 ++-- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/controllers/user.js b/controllers/user.js index cec8f7b..0e7b832 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -336,17 +336,20 @@ exports.checkToken = async (req, res, next) => } } +// Reçoit les données du formulaire de connexion avec mot de passe. exports.login = async (req, res, next) => { try { const db = require("../models/index"); + // Est-ce qu'un compte existe pour l'adresse e-mail envoyée ? const emailSend=tool.trimIfNotNull(req.body.email); const user=await db["User"].findOne({ attributes: ["id", "password", "email", "name", "status"], where: { email: emailSend } }); if(!user) res.status(404).json({ errors: [txt.emailNotFound] }); else { + // Est-ce ce compte a déjà été validé par l'utilisateur ? Si non, on lui envoie un nouveau lien de validation. const subscription=await db["Subscription"].findOne({ attributes: ["id"], where: { UserId: user.id } }); if(!subscription) { @@ -356,30 +359,35 @@ exports.login = async (req, res, next) => else { const nowTS=new Date().getTime(); + // L'utilisateur n'a-t-il pas testé de se connecter de trop nombreuses fois sans succès ? const countLogin=await toolFile.readJSON(config.dirTmpLogin, slugify(emailSend)); - if(countLogin && countLogin.nb >= config.maxLoginFail && countLogin.lastTime > (nowTS-config.loginFailTimeInMinutes*3600*1000)) + if(countLogin && countLogin.nb >= config.maxLoginFail && countLogin.lastTime > (nowTS-config.loginFailTimeInMinutes*60*1000)) res.status(401).json({ errors: [txt.tooManyLoginFails.replace("MINUTES", config.loginFailTimeInMinutes)] }); else { + // Le mot du passe envoyé est-il cohérent avec celui de la base de données après chiffrement ? const valid = await bcrypt.compare(req.body.password, user.password); if (!valid) { res.status(401).json({ errors: [txt.badPassword] }); + // On comptabilise l'erreur : let newCountLogin={ nb:1, lastTime:nowTS }; - if(countLogin.nb && countLogin.lastTime > (nowTS-config.loginFailTimeInMinutes*3600*1000)) + if(countLogin.nb && countLogin.lastTime > (nowTS-config.loginFailTimeInMinutes*60*1000)) newCountLogin.nb=countLogin.nb+1; await toolFile.createJSON(config.dirTmpLogin, slugify(emailSend), newCountLogin); } else { + // Si tout est ok, on enregistre la date de connexion + retourne un token de connexion. const now=new Date(); - const timeDifference=req.body.timeDifference;// permet d'actualiser en cas de déplacements/heures d'été, etc. + const timeDifference=req.body.timeDifference; db["User"].update({ connectedAt: now, timeDifference: timeDifference }, { where: { id : user.id }, limit:1 }); creaUserJson(user.id); + // Connexion à rallonge uniquement possible pour utilisateur de base : let loginTime=config.tokenConnexionMinTimeInHours; if((req.body.keepConnected==="true") && (user.status==="user")) loginTime=config.tokenConnexionMaxTimeInDays; - // si des données concernant un quiz ont été transmises, je les enregistre ici : + // Si des données concernant un quiz ont été transmises, on les enregistre ici : req.body.UserId=user.id; if(req.body.QuestionnaireId) { @@ -410,18 +418,21 @@ exports.login = async (req, res, next) => } } +// Reçoit les données du formulaire de connexion avec demande de recevoir un lien de connexion. exports.getLoginLink = async (req, res, next) => { try { + // Est-ce qu'un compte existe pour l'adresse e-mail envoyée ? const emailSend=tool.trimIfNotNull(req.body.email); const userDatas=await searchUserByEmail(emailSend); if(!userDatas) res.status(404).json({ errors: [txt.emailNotFound] }); - else if(userDatas.User.status!=="user") + else if(userDatas.User.status!=="user") // seuls les utilisateurs de base peuvent se connecter de cette façon. res.status(403).json({ errors: [txtGeneral.notAllowed] }); else { + // Est-ce ce compte a déjà été validé par l'utilisateur ? Si non, on lui envoie un nouveau lien de validation. if(!userDatas.Subscription) { await sendValidationLink(userDatas.User); @@ -447,7 +458,7 @@ exports.getLoginLink = async (req, res, next) => mailRecipientAddress: userDatas.User.email } await toolMail.sendMail(userDatas.User.smtp, userDatas.User.email, txt.mailLoginLinkSubject, tool.replaceAll(txt.mailLoginLinkBodyTxt, mapMail), "", mailDatas); - res.status(200).json({ message: txt.mailLoginLinkMessage+config.tokenLoginLinkTimeInHours+"." }); + res.status(200).json({ message: txt.mailLoginLinkMessage.replace("*TIMING*", config.tokenLoginLinkTimeInHours) }); } } next(); diff --git a/front/public/login.html b/front/public/login.html index fbe5ad2..e6b8eec 100644 --- a/front/public/login.html +++ b/front/public/login.html @@ -30,7 +30,7 @@
Logo WikiLerni

Cultivons notre jardin !

-
Si vous voyez ce message, c'est que votre lien de connexion n'est pas valide. Vous pouvez en demander un nouveau en cliquant ici.
+
Si vous voyez ce message, c'est que votre lien de connexion n'est pas valide ou a expiré. Vous pouvez en demander un nouveau en cliquant ici.