Ajout possibilité inscription simplifiée (uniquement email). Déplacement fonction JS générant des mots de passe dans le backend.
This commit is contained in:
parent
9f795e8b63
commit
b3312e9cf8
@ -61,6 +61,8 @@ exports.getGodfatherId = async (req, res, next) =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Contrôleur traitant les données envoyées pour une inscription
|
||||||
|
// Il peut n'y avoir qu'une adresse e-mail ou des données plus complètes (pseudo, parrain, etc.) dès l'inscription
|
||||||
exports.signup = async (req, res, next) =>
|
exports.signup = async (req, res, next) =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -68,10 +70,24 @@ exports.signup = async (req, res, next) =>
|
|||||||
const db = require("../models/index");
|
const db = require("../models/index");
|
||||||
if(req.body.cguOk !== "true")
|
if(req.body.cguOk !== "true")
|
||||||
res.status(400).json({ errors: [txt.needUGCOk] });
|
res.status(400).json({ errors: [txt.needUGCOk] });
|
||||||
else if(req.body.password.length < config.passwordMinLength) // si le champ est supprimé du formulaire d'inscription, générer un mot de passe ok ici
|
else if((req.body.password !== undefined) && (req.body.password.length < config.passwordMinLength))
|
||||||
res.status(400).json({ errors: [txt.needLongPassWord.replace("MIN_LENGTH", config.passwordMinLength)] });
|
res.status(400).json({ errors: [txt.needLongPassWord.replace("MIN_LENGTH", config.passwordMinLength)] });
|
||||||
|
else if(tool.isEmpty(req.body.email))
|
||||||
|
res.status(400).json({ errors: [txt.needEmail] });
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Dans le cas d'une inscription simplifiée, seule l'adresse e-mail est demandée :
|
||||||
|
if(tool.isEmpty(req.body.password))
|
||||||
|
req.body.password=tool.getPassword(8, 12);
|
||||||
|
req.body.password=await bcrypt.hash(req.body.password, config.bcryptSaltRounds);
|
||||||
|
// Si pas de pseudo envoyé, on utilise la partie de l'e-mail précédant le "@"
|
||||||
|
if(tool.isEmpty(req.body.name))
|
||||||
|
{
|
||||||
|
const lastIndex=req.body.email.indexOf("@");
|
||||||
|
if(lastIndex === -1)
|
||||||
|
lastIndex=1;
|
||||||
|
req.body.name=req.body.email.substring(0,lastIndex);
|
||||||
|
}
|
||||||
req.body.GodfatherId=null;
|
req.body.GodfatherId=null;
|
||||||
if(req.body.codeGodfather!=="")
|
if(req.body.codeGodfather!=="")
|
||||||
{
|
{
|
||||||
@ -79,7 +95,6 @@ exports.signup = async (req, res, next) =>
|
|||||||
if(godfather)
|
if(godfather)
|
||||||
req.body.GodfatherId=godfather.id;
|
req.body.GodfatherId=godfather.id;
|
||||||
}
|
}
|
||||||
req.body.password=await bcrypt.hash(req.body.password, config.bcryptSaltRounds);
|
|
||||||
const user=await db["User"].create({ ...req.body }, { fields: ["name", "email", "password", "newsletterOk", "GodfatherId", "timeDifference"] });
|
const user=await db["User"].create({ ...req.body }, { fields: ["name", "email", "password", "newsletterOk", "GodfatherId", "timeDifference"] });
|
||||||
req.body.UserId=user.id;
|
req.body.UserId=user.id;
|
||||||
// si l'utilisateur a répondu à un quiz avant de créer son compte, on enregistre son résultats.
|
// si l'utilisateur a répondu à un quiz avant de créer son compte, on enregistre son résultats.
|
||||||
|
@ -1,51 +1,42 @@
|
|||||||
// -- GESTION DU FORMULAIRE PERMETTANT DE CRÉER SON COMPTE
|
// -- PAGE AFFICHANT L'ÉLÉMENT D'UN GROUPE DE QUIZ ET PROPOSANT DE CRÉER SON COMPTE DE MANIÈRE SIMPLIFIÉE
|
||||||
|
|
||||||
/// L'utilisateur peut avoir répondu à un quiz avant d'arriver sur la page d'inscription
|
/// L'utilisateur peut avoir répondu à un quiz avant de lancer la création de son compte
|
||||||
/// Des ce cas il faut enregistrer son résultat en même temps que les informations de son compte
|
/// Dans ce cas il faut enregistrer son résultat en même temps que les informations de son compte
|
||||||
|
|
||||||
// Fichier de configuration tirés du backend :
|
// Fichier de configuration tirés du backend :
|
||||||
import { apiUrl, availableLangs, theme } from "../../config/instance.js";
|
import { apiUrl, availableLangs, theme } from "../../config/instance.js";
|
||||||
const lang=availableLangs[0];
|
const lang=availableLangs[0];
|
||||||
|
|
||||||
const configTemplate = require("../../views/"+theme+"/config/"+lang+".js");// besoin de toutes les déclarations, car appel dynamique : configTemplate[homePage]
|
const configTemplate = require("../../views/"+theme+"/config/"+lang+".js");// besoin de toutes les déclarations, car appel dynamique : configTemplate[homePage]
|
||||||
const configUsers = require("../../config/users");// idem pour configurer formulaire
|
const configUsers = require("../../config/users");// idem pour configurer formulaire
|
||||||
|
|
||||||
// Importation des fonctions utiles au script :
|
// Importation des fonctions utiles au script :
|
||||||
import { getLocaly, removeLocaly, saveLocaly } from "./tools/clientstorage.js";
|
import { getLocaly, removeLocaly } from "./tools/clientstorage.js";
|
||||||
import { addElement } from "./tools/dom.js";
|
import { addElement } from "./tools/dom.js";
|
||||||
import { helloDev } from "./tools/everywhere.js";
|
import { helloDev, updateAccountLink } from "./tools/everywhere.js";
|
||||||
import { getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
|
import { getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
|
||||||
import { loadMatomo } from "./tools/matomo.js";
|
import { loadMatomo } from "./tools/matomo.js";
|
||||||
import { checkAnswerDatas, checkSession, getPassword, getTimeDifference } from "./tools/users.js";
|
import { checkAnswerDatas, checkSession, getTimeDifference } from "./tools/users.js";
|
||||||
|
|
||||||
// Dictionnaires :
|
// Dictionnaires :
|
||||||
const { notRequired, serverError } = require("../../lang/"+lang+"/general");
|
const { serverError } = require("../../lang/"+lang+"/general");
|
||||||
const { alreadyConnected, godfatherFound, godfatherNotFound, needUniqueEmail, passwordCopied } = require("../../lang/"+lang+"/user");
|
const { needUniqueEmail } = require("../../lang/"+lang+"/user");
|
||||||
|
|
||||||
// Principaux éléments du DOM manipulés :
|
// Principaux éléments du DOM manipulés :
|
||||||
const myForm=document.getElementById("subscription");
|
|
||||||
const divResponse=document.getElementById("response");
|
|
||||||
const passwordInput=document.getElementById("password");
|
|
||||||
const passwordLink=document.getElementById("getPassword");
|
|
||||||
const passwordHelp=document.getElementById("passwordMessage");
|
|
||||||
const emailInput=document.getElementById("email");
|
|
||||||
const btnSubmit=document.getElementById("submitDatas");
|
const btnSubmit=document.getElementById("submitDatas");
|
||||||
const codeGodfatherInput=document.getElementById("codeGodfather");
|
const divResponse=document.getElementById("response");
|
||||||
|
const emailInput=document.getElementById("email");
|
||||||
|
const myForm=document.getElementById("subscription");
|
||||||
|
|
||||||
helloDev();
|
// Test de connexion de l'utilisateur + affichage formulaire d'inscription :
|
||||||
|
|
||||||
// Test de connexion de l'utilisateur + affichage formulaire d'inscription.
|
|
||||||
const initialise = async () =>
|
const initialise = async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const isConnected=await checkSession();
|
let isConnected=await checkSession(), user;
|
||||||
if(isConnected)
|
if(isConnected)
|
||||||
{
|
{
|
||||||
//saveLocaly("message", { message: alreadyConnected, color:"info" });// pour l'afficher sur la page suivante
|
user=getLocaly("user", true);
|
||||||
//const user=getLocaly("user", true);
|
updateAccountLink(user.status, configTemplate);// lien vers le compte adapté pour les utilisateurs connectés
|
||||||
//const homePage=user.status+"HomePage";
|
|
||||||
//window.location.assign("/"+configTemplate[homePage]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -61,18 +52,7 @@ const initialise = async () =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
initialise();
|
initialise();
|
||||||
|
helloDev();
|
||||||
// Générateur de mot de passe "aléatoire"
|
|
||||||
passwordLink.addEventListener("click", function(e)
|
|
||||||
{
|
|
||||||
e.preventDefault();
|
|
||||||
passwordInput.type="text";
|
|
||||||
passwordInput.value=getPassword(8, 12);
|
|
||||||
// Copie du mot de passe généré dans le "presse-papier" de l'ordinateur :
|
|
||||||
passwordInput.select();
|
|
||||||
document.execCommand("copy");
|
|
||||||
addElement(passwordHelp, "div", passwordCopied, "", ["success"]);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Test si l'e-mail saisi est déjà utilisé par un autre compte.
|
// Test si l'e-mail saisi est déjà utilisé par un autre compte.
|
||||||
// Si c'est le cas, la validation du formulaire est bloquée.
|
// Si c'est le cas, la validation du formulaire est bloquée.
|
||||||
@ -92,7 +72,7 @@ emailInput.addEventListener("blur", function(e)
|
|||||||
if (this.readyState == XMLHttpRequest.DONE)
|
if (this.readyState == XMLHttpRequest.DONE)
|
||||||
{
|
{
|
||||||
let response=JSON.parse(this.responseText);
|
let response=JSON.parse(this.responseText);
|
||||||
if (this.status === 200 && response.free!==undefined && response.free === false)
|
if (this.status === 200 && response.free !== undefined && response.free === false)
|
||||||
{
|
{
|
||||||
addElement(document.getElementById("emailMessage"), "div", needUniqueEmail.replace("#URL", configTemplate.connectionPage), "", ["error"]);
|
addElement(document.getElementById("emailMessage"), "div", needUniqueEmail.replace("#URL", configTemplate.connectionPage), "", ["error"]);
|
||||||
btnSubmit.setAttribute("disabled", true);
|
btnSubmit.setAttribute("disabled", true);
|
||||||
@ -107,34 +87,6 @@ emailInput.addEventListener("blur", function(e)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Vérification que le code/e-mail de parrainage saisi est valide.
|
|
||||||
codeGodfatherInput.addEventListener("focus", function(e)
|
|
||||||
{ // on efface l'éventuel message d'erreur si on revient sur le champ pour tester un autre code.
|
|
||||||
addElement(document.getElementById("codeGodfatherMessage"), "i", notRequired);
|
|
||||||
});
|
|
||||||
codeGodfatherInput.addEventListener("blur", function(e)
|
|
||||||
{
|
|
||||||
const codeValue=codeGodfatherInput.value.trim();
|
|
||||||
if(codeValue!=="")
|
|
||||||
{
|
|
||||||
const xhr = new XMLHttpRequest();
|
|
||||||
xhr.open("POST", apiUrl+configUsers.userRoutes+configUsers.getGodfatherRoute);
|
|
||||||
xhr.onreadystatechange = function()
|
|
||||||
{
|
|
||||||
if (this.readyState == XMLHttpRequest.DONE)
|
|
||||||
{
|
|
||||||
if (this.status === 204)
|
|
||||||
addElement(document.getElementById("codeGodfatherMessage"), "div", godfatherNotFound, "", ["error"]);
|
|
||||||
else
|
|
||||||
addElement(document.getElementById("codeGodfatherMessage"), "div", godfatherFound, "", ["success"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xhr.setRequestHeader("Content-Type", "application/json");
|
|
||||||
const datas={ codeTest:codeValue };
|
|
||||||
xhr.send(JSON.stringify(datas));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Traitement de l'envoi des données d'inscription :
|
// Traitement de l'envoi des données d'inscription :
|
||||||
myForm.addEventListener("submit", function(e)
|
myForm.addEventListener("submit", function(e)
|
||||||
{
|
{
|
||||||
@ -152,11 +104,14 @@ myForm.addEventListener("submit", function(e)
|
|||||||
{
|
{
|
||||||
myForm.style.display="none";
|
myForm.style.display="none";
|
||||||
addElement(divResponse, "p", response.message, "", ["success"]);
|
addElement(divResponse, "p", response.message, "", ["success"]);
|
||||||
removeLocaly("lastAnswer");// ! important pour ne pas enregister plusieurs fois le résultat.
|
removeLocaly("lastAnswer");// !! important, pour ne pas enregister plusieurs fois le résultat.
|
||||||
}
|
}
|
||||||
else if (response.errors)
|
else if (response.errors)
|
||||||
{
|
{
|
||||||
|
if(Array.isArray(response.errors))
|
||||||
response.errors = response.errors.join("<br>");
|
response.errors = response.errors.join("<br>");
|
||||||
|
else
|
||||||
|
response.errors = serverError;
|
||||||
addElement(divResponse, "p", response.errors, "", ["error"]);
|
addElement(divResponse, "p", response.errors, "", ["error"]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -168,7 +123,7 @@ myForm.addEventListener("submit", function(e)
|
|||||||
if(datas)
|
if(datas)
|
||||||
{
|
{
|
||||||
datas.timeDifference=getTimeDifference(configUsers);
|
datas.timeDifference=getTimeDifference(configUsers);
|
||||||
// si l'utilisateur a précédement répondu à un quiz, j'ajoute les infos de son résultat :
|
// si l'utilisateur a précédement répondu à un quiz, on ajoute les données de son résultat :
|
||||||
datas=checkAnswerDatas(datas);
|
datas=checkAnswerDatas(datas);
|
||||||
xhr.send(JSON.stringify(datas));
|
xhr.send(JSON.stringify(datas));
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ import { getLocaly, removeLocaly } from "./tools/clientstorage.js";
|
|||||||
import { addElement } from "./tools/dom.js";
|
import { addElement } from "./tools/dom.js";
|
||||||
import { helloDev, updateAccountLink } from "./tools/everywhere.js";
|
import { helloDev, updateAccountLink } from "./tools/everywhere.js";
|
||||||
import { empyForm, getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
|
import { empyForm, getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
|
||||||
import { dateFormat, isEmpty, replaceAll } from "../../tools/main";
|
import { dateFormat, getPassword, isEmpty, replaceAll } from "../../tools/main";
|
||||||
import { getUrlParams } from "./tools/url.js";
|
import { getUrlParams } from "./tools/url.js";
|
||||||
import { checkSession, getPassword } from "./tools/users.js";
|
import { checkSession } from "./tools/users.js";
|
||||||
|
|
||||||
// Dictionnaires :
|
// Dictionnaires :
|
||||||
const { addOkMessage, serverError } = require("../../lang/"+lang+"/general");
|
const { addOkMessage, serverError } = require("../../lang/"+lang+"/general");
|
||||||
|
@ -15,8 +15,9 @@ import { getLocaly, removeLocaly, saveLocaly } from "./tools/clientstorage.js";
|
|||||||
import { addElement } from "./tools/dom.js";
|
import { addElement } from "./tools/dom.js";
|
||||||
import { helloDev } from "./tools/everywhere.js";
|
import { helloDev } from "./tools/everywhere.js";
|
||||||
import { getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
|
import { getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
|
||||||
|
import { getPassword } from "../../tools/main";
|
||||||
import { loadMatomo } from "./tools/matomo.js";
|
import { loadMatomo } from "./tools/matomo.js";
|
||||||
import { checkAnswerDatas, checkSession, getPassword, getTimeDifference } from "./tools/users.js";
|
import { checkAnswerDatas, checkSession, getTimeDifference } from "./tools/users.js";
|
||||||
|
|
||||||
// Dictionnaires :
|
// Dictionnaires :
|
||||||
const { notRequired, serverError } = require("../../lang/"+lang+"/general");
|
const { notRequired, serverError } = require("../../lang/"+lang+"/general");
|
||||||
|
@ -18,25 +18,6 @@ export const getTimeDifference = () =>
|
|||||||
return timeLocal;
|
return timeLocal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On enlève volontairement les 0/O pour éviter les confusions !
|
|
||||||
// Et mieux vaut aussi débuter et finir par une lettre simple.
|
|
||||||
export const getPassword = (nbCarMin, nbCarMax) =>
|
|
||||||
{
|
|
||||||
const nbCar=nbCarMin+Math.floor(Math.random()*(nbCarMax-nbCarMin));
|
|
||||||
const letters="ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz";
|
|
||||||
const others="123456789!?.*-_%@&ÉÀÈÙ€$ÂÊÛÎ";
|
|
||||||
let password=letters[Math.floor(Math.random()*letters.length)];
|
|
||||||
for(let i=1;i<(nbCar-1);i++)
|
|
||||||
{
|
|
||||||
if((i % 2) ===1)
|
|
||||||
password+=others[Math.floor(Math.random()*others.length)];
|
|
||||||
else
|
|
||||||
password+=letters[Math.floor(Math.random()*letters.length)];
|
|
||||||
}
|
|
||||||
password+=letters[Math.floor(Math.random()*letters.length)];
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
// J'utilise le stockage local du navigateur pour enregistrer les données permettant de reconnaître l'utilisateur par la suite
|
// J'utilise le stockage local du navigateur pour enregistrer les données permettant de reconnaître l'utilisateur par la suite
|
||||||
// Seul le serveur pourra vérifier que les identifiants sont (toujours) valides.
|
// Seul le serveur pourra vérifier que les identifiants sont (toujours) valides.
|
||||||
export const setSession = (userId, token, durationTS) =>
|
export const setSession = (userId, token, durationTS) =>
|
||||||
|
@ -76,6 +76,25 @@ class Tool
|
|||||||
else
|
else
|
||||||
return myMounth+"/"+myDay+"/"+myYear;
|
return myMounth+"/"+myDay+"/"+myYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On enlève volontairement les 0/O pour éviter les confusions !
|
||||||
|
// Et mieux vaut aussi débuter et finir par une lettre simple.
|
||||||
|
static getPassword (nbCarMin, nbCarMax)
|
||||||
|
{
|
||||||
|
const nbCar=nbCarMin+Math.floor(Math.random()*(nbCarMax-nbCarMin));
|
||||||
|
const letters="ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz";
|
||||||
|
const others="123456789!?.*-_%@&ÉÀÈÙ€$ÂÊÛÎ";
|
||||||
|
let password=letters[Math.floor(Math.random()*letters.length)];
|
||||||
|
for(let i=1;i<(nbCar-1);i++)
|
||||||
|
{
|
||||||
|
if((i % 2) ===1)
|
||||||
|
password+=others[Math.floor(Math.random()*others.length)];
|
||||||
|
else
|
||||||
|
password+=letters[Math.floor(Math.random()*letters.length)];
|
||||||
|
}
|
||||||
|
password+=letters[Math.floor(Math.random()*letters.length)];
|
||||||
|
return password;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Tool;
|
module.exports = Tool;
|
@ -85,7 +85,7 @@ block content
|
|||||||
strong #{configTpl.noJSNotification}
|
strong #{configTpl.noJSNotification}
|
||||||
- const cguOkLabel = txtUser.formsCGUOkLabel.replace("#link", "/"+configTpl.cguPage); /// remettre class="needJS" au formulaire ci-dessous
|
- const cguOkLabel = txtUser.formsCGUOkLabel.replace("#link", "/"+configTpl.cguPage); /// remettre class="needJS" au formulaire ci-dessous
|
||||||
div#quizElementSignupForm
|
div#quizElementSignupForm
|
||||||
form(id="subscription" method="POST")
|
form(id="subscription" method="POST" class="needJS")
|
||||||
h3 #{configTpl.quizElementSubcriptionFormTitle}
|
h3 #{configTpl.quizElementSubcriptionFormTitle}
|
||||||
fieldset
|
fieldset
|
||||||
label(for="email") #{txtUser.formsEmailLabel}
|
label(for="email") #{txtUser.formsEmailLabel}
|
||||||
|
@ -58,7 +58,7 @@ block content
|
|||||||
div
|
div
|
||||||
strong #{configTpl.noJSNotification}
|
strong #{configTpl.noJSNotification}
|
||||||
// à cacher si pas de JS !
|
// à cacher si pas de JS !
|
||||||
form(id="group" method="POST")
|
form(id="group" method="POST" class="needJS")
|
||||||
h2 #{group.Group.title}
|
h2 #{group.Group.title}
|
||||||
div#response
|
div#response
|
||||||
div(class="subscribeBtns")
|
div(class="subscribeBtns")
|
||||||
|
Loading…
Reference in New Issue
Block a user