Skip to content

Commit

Permalink
Merge pull request #54 from WildCodeSchool-2023-09/S03US05_Add+Security
Browse files Browse the repository at this point in the history
Fix Register Verif
  • Loading branch information
fgaujard authored Jan 10, 2024
2 parents ac0567d + 0aa56a5 commit 19a93f0
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 119 deletions.
10 changes: 5 additions & 5 deletions backend/database/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ USE eating_nam_nam;
#Create tables for eating nam nam DB
CREATE TABLE user (
ID INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
username VARCHAR(30) NOT NULL,
email VARCHAR(80) NOT NULL,
firstname VARCHAR(30),
lastname VARCHAR(50),
username VARCHAR(20) UNIQUE NOT NULL,
email VARCHAR(30) UNIQUE NOT NULL,
firstname VARCHAR(20),
lastname VARCHAR(20),
birthdate DATE,
password VARCHAR(256) NOT NULL,
password VARCHAR(255) NOT NULL,
description MEDIUMTEXT,
is_admin BIT,
avatar VARCHAR(200)
Expand Down
35 changes: 27 additions & 8 deletions backend/src/controllers/userControllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,34 @@ const read = async (req, res, next) => {
const add = async (req, res, next) => {
// Extract the user data from the request body
const item = req.body;
try {
// Insert the user into the database
const insertId = await tables.user.create(item);

// Respond with HTTP 201 (Created) and the ID of the newly inserted user
res.status(201).json({ insertId });
} catch (err) {
// Pass any errors to the error-handling middleware
next(err);
const existingUsername = await tables.user.readByUsername(item.username);
const existingEmail = await tables.user.readByEmail(item.email);

if (existingUsername && existingEmail) {
res.status(400).json({
message:
"Il semblerait qu'un compte soit déjà existant avec ce nom d'utilisateur et cette adresse email, essayez de vous connecter",
});
} else if (existingUsername) {
res.status(400).json({ message: "Nom d'utilisateur déjà utilisé" });
} else if (existingEmail) {
res
.status(400)
.json({ message: "Cette adresse mail est déjà associé avec un compte" });
}

if (!existingUsername && !existingEmail) {
try {
// Insert the user into the database
const insertId = await tables.user.create(item);

// Respond with HTTP 201 (Created) and the ID of the newly inserted user
res.status(201).json({ insertId });
} catch (err) {
// Pass any errors to the error-handling middleware
next(err);
}
}
};

Expand Down
19 changes: 7 additions & 12 deletions backend/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ const router = express.Router();

// Import userControllers module for handling item-related operations
const UserControllers = require("./controllers/userControllers");
const AuthControllers = require("./controllers/authControllers");

// Import the middleware for hash password in DB when a new user register
const hashPasswordMiddleware = require("./middleware/hashpassMiddleware");

router.get("/users", UserControllers.browse); // Route to get a list of items
router.get("/users/:id", UserControllers.read); // Route to get a specific item by ID
router.post("/users", hashPasswordMiddleware, UserControllers.add);

// Route to get specific items and block the register if they exists
router.get("/username/:username", AuthControllers.readByUsername);
router.get("/email/:email", AuthControllers.readByEmail);
router.post("/login", AuthControllers.login);

/* ************************************************************************* */
// RECIPE
/* ************************************************************************* */
Expand Down Expand Up @@ -88,18 +95,6 @@ router.get("/users", UserControllers.browse);
router.get("/recipes", RecipeControllers.browse);
router.get("/tags", TagControllers.browse);

/* ************************************************************************* */
// AUTH
/* ************************************************************************* */

// Import authControllers module for register and connection
const AuthControllers = require("./controllers/authControllers");

// Route to get specific items and block the register if they exists
router.get("/username/:username", AuthControllers.readByUsername);
router.get("/email/:email", AuthControllers.readByEmail);
router.post("/login", AuthControllers.login);

/* ************************************************************************* */

module.exports = router;
34 changes: 34 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

103 changes: 47 additions & 56 deletions frontend/src/pages/Connexion.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ import {
resetErrMsgPassSign,
resetErrMsgPassConfSign,
resetAllErrMsgSign,
} from "./services/postUserVerif";
} from "./services/postUserValid";
import "react-toastify/dist/ReactToastify.css";
import "./style/Connexion.scss";

// Formulaires de LogIn ou SignIn

function TypeOfForm({ checkbox, setCheckbox }) {
const [success, setSuccess] = useState(false);

const handleClickLogin = async (event) => {
event.preventDefault();

Expand All @@ -32,6 +30,13 @@ function TypeOfForm({ checkbox, setCheckbox }) {

loginErrorMsg.innerText = "";

if (!username) {
usernameErrorMsg.innerText = "Veuillez saisir votre nom d'utilisateur";
}
if (!password) {
passwordErrorMsg.innerText = "Veuillez saisir votre mot de passe";
}

if (username && password) {
usernameErrorMsg.innerText = "";
passwordErrorMsg.innerText = "";
Expand All @@ -52,8 +57,8 @@ function TypeOfForm({ checkbox, setCheckbox }) {
// Redirection vers la page de connexion si la création réussit

if (response && response.status === 200) {
const user = response.data;
console.info(user);
const userLogged = response.data;
console.info("user =", userLogged);
toast.success(
"Authentification réussie ! 😎 Redirection en cours..",
{
Expand All @@ -72,15 +77,9 @@ function TypeOfForm({ checkbox, setCheckbox }) {
}
} catch (err) {
// Log des erreurs possibles
console.error(err);
console.info(err);
}
}
if (!username) {
usernameErrorMsg.innerText = "Veuillez saisir votre nom d'utilisateur";
}
if (!password) {
passwordErrorMsg.innerText = "Veuillez saisir votre mot de passe";
}
};

// Vérifie en temps réel si le password est valide et qu'il correspond au passConf si celui-ci est renseigné
Expand All @@ -93,54 +92,46 @@ function TypeOfForm({ checkbox, setCheckbox }) {
// Actions réalisés au submit "Connexion"
const handleClickRegister = (event) => {
event.preventDefault();
// Verification du formulaire d'inscription

isValidUsername().then((usernameIsValid) => {
// Ici avec le '.then' on attend le retour de la fonction async qui cherche dans la BDD si l'utilisateur existe
// La fonction renvoie une valeur 'true' ou 'false' contenu dans "usernameIsValid"

isValidEmail().then((emailIsValid) => {
// Ici avec le '.then' on attend le retour de la fonction async qui cherche dans la BDD si l'email existe
// La fonction renvoie une valeur 'true' ou 'false' contenu dans "usernameIsValid"

// Puis le reste des verifications s'exécute et renvoient une valeur 'true' ou 'false'
const passwordIsValid = isValidPassword();
const passConfIsValid = isPassMatch();
// Verification du formulaire d'inscription
const usernameIsValid = isValidUsername();
const emailIsValid = isValidEmail();
const passwordIsValid = isValidPassword();
const passConfIsValid = isPassMatch();

// Si tout est OK (true) on exécute la suite du code
if (
usernameIsValid &&
emailIsValid &&
passwordIsValid &&
passConfIsValid
) {
// Récuperation des valeurs du formulaire
const username = document.querySelector("#username");
const email = document.querySelector("#email");
const password = document.querySelector("#password");
// Si tout est OK (true) on exécute la suite du code
if (usernameIsValid && emailIsValid && passwordIsValid && passConfIsValid) {
// Récuperation des valeurs du formulaire
const username = document.querySelector("#username").value;
const email = document.querySelector("#email").value;
const password = document.querySelector("#password").value;

// Création de l'objet contenant la data à envoyer
const formData = {
username: username.value,
email: email.value,
password: password.value,
};
// Création de l'objet contenant la data à envoyer
const formData = {
username,
email,
password,
};

// Envoie des données vers notre API
axios
.post(`${import.meta.env.VITE_BACKEND_URL}/api/users`, formData)
.then(() => setSuccess(!success))
.catch((err) => console.error(err));
// Envoie des données vers notre API
axios
.post(`${import.meta.env.VITE_BACKEND_URL}/api/users`, formData)
.then((res) => {
if (res.status === 201) {
// Message pop-up de succès
toast.success("Votre compte à bien été créé ! 😎");

// Rechargement de la page
toast.success("Votre compte à bien été créé ! 😎");
document.getElementsByTagName("form")[2].email.value = "";
if (!checkbox) setCheckbox(true);
else setCheckbox(false);
}
});
console.error("Saisie du formulaire incorrect");
});
// Redirection sur le login en gardant la valeur de username
document.getElementsByTagName("form")[2].email.value = "";
if (!checkbox) setCheckbox(true);
console.info("response =", res);
}
})
.catch((err) => {
// Affiche un pop-up du message d'erreur
toast.error(err.response.data.message);
});
} else toast.error("Saisie du formulaire incorrect 🫠");
};

// Affiche soit un formulaire de connexion soit d'inscription
Expand All @@ -165,7 +156,7 @@ function TypeOfForm({ checkbox, setCheckbox }) {
</form>
) : (
// Formulaire d'inscription
// Les fonctions 'onBlur' et 'onFocus' permettent de vérifier et d'afficher "en temps réel" si il y a des erreurs lors de la saisie du formaulaire
// Les fonctions 'onBlur' et 'onFocus' permettent de vérifier et d'afficher "en temps réel" si il y a des erreurs lors de la saisie du formulaire
<form className="form" id="form" onSubmit={handleClickRegister}>
{/* Label et champ du nom d'utilisateur */}
<label htmlFor="username">Nom d'utilisateur :</label>
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import axios from "axios";

async function isValidUsername() {
function isValidUsername() {
// Récupère le champ username et la balise erreur correspondante
const username = document.querySelector("#username").value;
const usernameErrorMsg = document.querySelector("#username-error");
Expand All @@ -11,28 +9,12 @@ async function isValidUsername() {
"Le nom d'utilisateur doit contenir 5 à 20 caractères.";
return false;
}
// Verifie si l'utilisateur existe dans la BDD
try {
const response = await axios.get(
`${import.meta.env.VITE_BACKEND_URL}/api/username/${username}`
);
// Si oui : retourne un mdg d'erreur dans la balise, et la fonction renvoie false
if (response.data.username === username) {
usernameErrorMsg.innerText = "Le nom d'utilisateur est déjà utilisé";
return false;
}
} catch (error) {
// Si on obtient une erreur 404, cela signifie que l'utilisateur n'existe pas dans la BDD
if (error.response.status === 404) {
usernameErrorMsg.innerText = ""; // Aucune erreur n'est affichée dans ce cas
}
}

// Sinon la fonction renvoie 'true' sans message d'erreur pour indiquer le username comme OK
return true;
}

async function isValidEmail() {
function isValidEmail() {
// Récupère le champ email et la balise erreur correspondante
const email = document.querySelector("#email").value;
const emailErrorMsg = document.querySelector("#email-error");
Expand All @@ -49,24 +31,6 @@ async function isValidEmail() {
return false;
}

// Verifie si l'email existe dans la BDD
try {
const response = await axios.get(
`${import.meta.env.VITE_BACKEND_URL}/api/email/${email}`
);
// Si oui : retourne un msg d'erreur dans la balise, et la fonction renvoie false
if (response.data.email === email) {
emailErrorMsg.innerText =
"Cette adresse email est déjà utilisé avec un autre compte.";
console.info(emailErrorMsg.innerText);
return false;
}
} catch (error) {
// Si on obtient une erreur 404, cela signifie que l'email n'existe pas dans la BDD
if (error.response.status === 404) {
emailErrorMsg.innerText = ""; // Aucune erreur n'est affichée dans ce cas
}
}
// Sinon la fonction renvoie 'true' sans message d'erreur pour indiquer le mail comme OK
return true;
}
Expand Down

0 comments on commit 19a93f0

Please sign in to comment.