diff --git a/controllers/user.js b/controllers/user.js
index 8c8a7ae..8c63529 100644
--- a/controllers/user.js
+++ b/controllers/user.js
@@ -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) =>
{
try
@@ -68,10 +70,24 @@ exports.signup = async (req, res, next) =>
const db = require("../models/index");
if(req.body.cguOk !== "true")
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)] });
+ else if(tool.isEmpty(req.body.email))
+ res.status(400).json({ errors: [txt.needEmail] });
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;
if(req.body.codeGodfather!=="")
{
@@ -79,7 +95,6 @@ exports.signup = async (req, res, next) =>
if(godfather)
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"] });
req.body.UserId=user.id;
// si l'utilisateur a répondu à un quiz avant de créer son compte, on enregistre son résultats.
diff --git a/front/src/groupElement.js b/front/src/groupElement.js
index 1201d90..015688c 100644
--- a/front/src/groupElement.js
+++ b/front/src/groupElement.js
@@ -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
-/// Des ce cas il faut enregistrer son résultat en même temps que les informations de son compte
+/// L'utilisateur peut avoir répondu à un quiz avant de lancer la création 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 :
import { apiUrl, availableLangs, theme } from "../../config/instance.js";
const lang=availableLangs[0];
-
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
// 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 { helloDev } from "./tools/everywhere.js";
+import { helloDev, updateAccountLink } from "./tools/everywhere.js";
import { getDatasFromInputs, setAttributesToInputs } from "./tools/forms.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 :
-const { notRequired, serverError } = require("../../lang/"+lang+"/general");
-const { alreadyConnected, godfatherFound, godfatherNotFound, needUniqueEmail, passwordCopied } = require("../../lang/"+lang+"/user");
+const { serverError } = require("../../lang/"+lang+"/general");
+const { needUniqueEmail } = require("../../lang/"+lang+"/user");
// 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 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 () =>
{
try
{
- const isConnected=await checkSession();
+ let isConnected=await checkSession(), user;
if(isConnected)
{
- //saveLocaly("message", { message: alreadyConnected, color:"info" });// pour l'afficher sur la page suivante
- //const user=getLocaly("user", true);
- //const homePage=user.status+"HomePage";
- //window.location.assign("/"+configTemplate[homePage]);
+ user=getLocaly("user", true);
+ updateAccountLink(user.status, configTemplate);// lien vers le compte adapté pour les utilisateurs connectés
}
else
{
@@ -61,18 +52,7 @@ const initialise = async () =>
}
}
initialise();
-
-// 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"]);
-});
+helloDev();
// 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.
@@ -92,7 +72,7 @@ emailInput.addEventListener("blur", function(e)
if (this.readyState == XMLHttpRequest.DONE)
{
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"]);
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 :
myForm.addEventListener("submit", function(e)
{
@@ -152,11 +104,14 @@ myForm.addEventListener("submit", function(e)
{
myForm.style.display="none";
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)
{
- response.errors = response.errors.join("
");
+ if(Array.isArray(response.errors))
+ response.errors = response.errors.join("
");
+ else
+ response.errors = serverError;
addElement(divResponse, "p", response.errors, "", ["error"]);
}
else
@@ -168,7 +123,7 @@ myForm.addEventListener("submit", function(e)
if(datas)
{
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);
xhr.send(JSON.stringify(datas));
}
diff --git a/front/src/manageUsers.js b/front/src/manageUsers.js
index 96d8432..075c0c3 100644
--- a/front/src/manageUsers.js
+++ b/front/src/manageUsers.js
@@ -20,9 +20,9 @@ import { getLocaly, removeLocaly } from "./tools/clientstorage.js";
import { addElement } from "./tools/dom.js";
import { helloDev, updateAccountLink } from "./tools/everywhere.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 { checkSession, getPassword } from "./tools/users.js";
+import { checkSession } from "./tools/users.js";
// Dictionnaires :
const { addOkMessage, serverError } = require("../../lang/"+lang+"/general");
diff --git a/front/src/subscribe.js b/front/src/subscribe.js
index 27c5a07..c4b4eef 100644
--- a/front/src/subscribe.js
+++ b/front/src/subscribe.js
@@ -15,8 +15,9 @@ import { getLocaly, removeLocaly, saveLocaly } from "./tools/clientstorage.js";
import { addElement } from "./tools/dom.js";
import { helloDev } from "./tools/everywhere.js";
import { getDatasFromInputs, setAttributesToInputs } from "./tools/forms.js";
+import { getPassword } from "../../tools/main";
import { loadMatomo } from "./tools/matomo.js";
-import { checkAnswerDatas, checkSession, getPassword, getTimeDifference } from "./tools/users.js";
+import { checkAnswerDatas, checkSession, getTimeDifference } from "./tools/users.js";
// Dictionnaires :
const { notRequired, serverError } = require("../../lang/"+lang+"/general");
diff --git a/front/src/tools/users.js b/front/src/tools/users.js
index ea7a3f4..812da29 100644
--- a/front/src/tools/users.js
+++ b/front/src/tools/users.js
@@ -18,25 +18,6 @@ export const getTimeDifference = () =>
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
// Seul le serveur pourra vérifier que les identifiants sont (toujours) valides.
export const setSession = (userId, token, durationTS) =>
diff --git a/tools/main.js b/tools/main.js
index 054df57..e684989 100644
--- a/tools/main.js
+++ b/tools/main.js
@@ -76,6 +76,25 @@ class Tool
else
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;
\ No newline at end of file
diff --git a/views/wikilerni/quiz-element.pug b/views/wikilerni/quiz-element.pug
index 5f1d06d..a9a3bfb 100644
--- a/views/wikilerni/quiz-element.pug
+++ b/views/wikilerni/quiz-element.pug
@@ -85,7 +85,7 @@ block content
strong #{configTpl.noJSNotification}
- const cguOkLabel = txtUser.formsCGUOkLabel.replace("#link", "/"+configTpl.cguPage); /// remettre class="needJS" au formulaire ci-dessous
div#quizElementSignupForm
- form(id="subscription" method="POST")
+ form(id="subscription" method="POST" class="needJS")
h3 #{configTpl.quizElementSubcriptionFormTitle}
fieldset
label(for="email") #{txtUser.formsEmailLabel}
diff --git a/views/wikilerni/quiz-group.pug b/views/wikilerni/quiz-group.pug
index 41ee537..302d979 100644
--- a/views/wikilerni/quiz-group.pug
+++ b/views/wikilerni/quiz-group.pug
@@ -58,7 +58,7 @@ block content
div
strong #{configTpl.noJSNotification}
// à cacher si pas de JS !
- form(id="group" method="POST")
+ form(id="group" method="POST" class="needJS")
h2 #{group.Group.title}
div#response
div(class="subscribeBtns")