mot de passe oublié

master
Noan07 2 years ago
parent 7e41fc2295
commit b493bc103f

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

@ -1,12 +1,13 @@
import axios from 'axios';
import React, { useState } from 'react';
import axios from 'axios';
//e.preventDefaul(); pour ne pas recharcher la page
const Connexion = (props) => {
const [errorMessage] = useState(props.error);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [forgotPassword, setForgotPassword] = useState(false);
const [forgotPasswordEmail, setForgotPasswordEmail] = useState('');
const [forgotPasswordMessage, setForgotPasswordMessage] = useState('');
const handleLogin = (e) => {
e.preventDefault();
@ -32,52 +33,89 @@ const Connexion = (props) => {
})
.catch((err) => {
console.log(err);
});
};
const handleForgotPassword = (e) => {
e.preventDefault();
axios({
method: "post",
url:`${process.env.REACT_APP_API_URL}api/user/forgotpassword`,
withCredentials: true,
data: {
email: forgotPasswordEmail,
},
})
.then((res) => {
if(res.data.message){
setForgotPasswordMessage(res.data.message);
}
})
.catch((err) => {
console.log(err);
});
};
return (
<div className='formulaire'>
<form className='cadre' action='' onSubmit={handleLogin} id="sign-up-form">
<h1>Connexion</h1>
{forgotPassword ? (
<form className='cadre' action='' onSubmit={handleForgotPassword} id="forgot-password-form">
<h1>Mot de passe oublié</h1>
<div className='inputbox'>
<span>email</span>
<input
type="text"
name="forgotPasswordEmail"
id="forgotPasswordEmail"
onChange={(e) => setForgotPasswordEmail (e.target.value)}
value={forgotPasswordEmail}/>
</div>
<br />
<input type="submit" value="Envoyer un mail de réinitialisation" id='send-reset-email' />
<br/>
{forgotPasswordMessage && <h4 className='success'>{forgotPasswordMessage}</h4>}
</form>
) : (
<form className='cadre' action='' onSubmit={handleLogin} id="sign-up-form">
<h1>Connexion</h1>
<div className='inputbox'>
<span>email</span>
<input
type="text"
name="email"
id="email"
onChange={(e) => setEmail (e.target.value)}
value={email}/>
<div className="email error"></div>
<input
type="text"
name="email"
id="email"
onChange={(e) => setEmail (e.target.value)}
value={email}/>
<div className="email error"></div>
</div>
<br />
<div className="inputbox">
<span>mot de passe</span>
<input
type="password"
name="password"
id="password"
onChange={(e) => setPassword (e.target.value)}
value={password}/>
<div className="password error"></div>
</div>
<span>mot de passe</span>
<input
type="password"
name="password"
id="password"
onChange={(e) => setPassword (e.target.value)}
value={password}/>
<div className="password error"></div>
</div>
<br />
<input type="submit" value="connexion" id='connexion' />
<br/>
<p className='mdp'>Mot de passe oublié?</p>
<br />
{errorMessage && <h4 className='success'>
Enregistrement réussi, veuillez-vous connecter
</h4>}
<br />
<input type="submit" value="connexion" id='connexion' />
<br/>
</form>
</div>
);
<p className='mdp' onClick={() => setForgotPassword(true)}>Mot de passe oublié?</p>
<br />
{errorMessage && <h4 className='success'>Enregistrement réussi, veuillez-vous connecter</h4>}
</form>
)}
</div>
);
};
//ce qui écrit dans le input est récuperé par le state
export default Connexion;

@ -9,8 +9,12 @@ const Inscription = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [controlPassword, setControlPassword] = useState('');
const [Popup, setPopup] = useState(false);
const [token, setToken] = useState('');
const [isVerified, setIsVerified] = useState(false);
const handleRegister = async (e) => {
e.preventDefault();
const terms = document.getElementById("terms");
@ -112,7 +116,7 @@ const Inscription = () => {
<input type="checkbox"
name="terms"
id="terms"/>
<span>J'accepte les <a href="/" target="_blank" rel='noopener noreferrer'>conditions générales</a></span>
<span>J'accepte les <a className='cond' onClick={() => setPopup(true)}>conditions générales</a></span>
<div className="terms error"></div>
</div>
<br />
@ -121,6 +125,25 @@ const Inscription = () => {
</form>
</div>
)}
{Popup && (
<div className="popup-conditions">
<div className="modal">
<h3>Conditions générales</h3>
<span className="cross" onClick={() => setPopup(false)}>
&#10005;
</span>
<p>Voici les conditions générales que vous devez respectés:</p>
<p>L'utilisation de notre réseau social est réservée à un usage personnel et non commercial.</p>
<p>Les utilisateurs s'engagent à ne pas partager de contenus illégaux, offensants ou violant les droits d'autrui.</p>
<p>Nous nous réservons le droit de supprimer tout contenu non conforme à ces conditions d'utilisation.</p>
<p>Les utilisateurs sont responsables de tout contenu qu'ils partagent sur notre réseau social.</p>
<p>Nous nous réservons le droit de suspendre ou de résilier l'accès de tout utilisateur en cas de non-respect de ces conditions d'utilisation.</p>
<p>Nous nous engageons à protéger la vie privée de nos utilisateurs conformément à notre politique de confidentialité.</p>
<p>Nous nous réservons le droit de modifier ces conditions d'utilisation à tout moment. Il est de la responsabilité de l'utilisateur de se tenir informé des modifications apportées.</p>
<p>En utilisant notre réseau social, les utilisateurs acceptent ces conditions d'utilisation.</p>
</div>
</div>
)}
</>
);
};

@ -2,6 +2,7 @@ import React, { useState } from 'react';
import Connexion from './Connexion';
import Inscription from './Inscription';
import Logo from '../../assets/img/logo.png';
import Img from '../../assets/img/insc.png';
const Log = ( props ) => {
const [signUpModal, setSignUpModal] = useState(props.signup);
@ -22,8 +23,8 @@ const Log = ( props ) => {
<div className='form-presentation'>
<img src={Logo} alt='Favor'/>
<p>Bienvenue!</p>
<p>"Comment découvrir et partager des sites et des ressources sur internet de manière plus efficace et personnalisée ?"</p>
<p></p>
<p>Qu'est ce que Favor?</p>
<p>Un réseau social de partage de liens, dont vous pourrez partager vos liensfefezfefezfzefzfz</p>
</div>
<div className="form-container">
<div className="info-form-container">
@ -56,6 +57,7 @@ const Log = ( props ) => {
Se connecter
</li>
</ul>
<img src={Img} className="imginsc"/>
</div>
{signUpModal && <Inscription />}
{signInModal && <Connexion />}

@ -7,6 +7,7 @@ import Discover from '../../pages/Discover.js';
import Profil from '../../pages/Profil.js';
import Configuration from '../../pages/Configuration.js';
import SearchBar from '../../pages/SearchBar.js';
import ResetPassword from '../../pages/ResetPassword.js';
const index = () => {
return (
@ -20,6 +21,7 @@ const index = () => {
{/* <Route path="*" element={<HomeNavigation/>} /> */}
<Route path="/Profil/:uid" element={<Profil/>} />
<Route path="/Configuration" element={<Configuration/>}/>
<Route path="/reset/:token" element={<ResetPassword />}/>
</Routes>
</BrowserRouter>
);

@ -59,87 +59,6 @@ const Profil = () => {
return (
<div>
<Navbar />
{/* <main>
<div id="bandeauProfil">
<h1 classNameName='affichage-date'>Compte créé le : {dateParser(userData.createdAt)}</h1>
<div id="image">
<img id="PhotoProfile" alt="Profil" src={userData.picture}/>
</div>
<div id="blocName">
<h1>{userData.pseudo}</h1>
<h2 classNameName="subdo">@{userData.pseudo}</h2>
<div>
<div id="blocAbonnement">
<div onClick={() => setFollowingPopup(true)} classNameName="bloc-aboonnements-abonner">
<div classNameName="nombre">{userData.following.length}</div>
<div classNameName="texteNombre">Abonnement</div>
</div>
<div onClick={() => setFollowerPopup(true)} classNameName="bloc-aboonnements-abonner">
<div classNameName="nombre">{userData.followers.length}</div>
<div classNameName="texteNombre">Abonnée</div>
</div>
{followingPopup && (
<div classNameName="popup-profil-container">
<div classNameName="modal">
<h3>Abonnements</h3>
<span classNameName="cross" onClick={() => setFollowingPopup(false)}>
&#10005;
</span>
<ul>
{usersData.map((user) => {
for (let i = 0; i < userData.following.length; i++) {
if (user._id === userData.following[i]) {
return (
<li key={user._id}>
<img src={user.picture} alt="user-pic" />
<h4>{user.pseudo}</h4>
<div classNameName="follow-handler">
<FollowHandler idToFollow={user._id} type={'card'}/>
</div>
</li>
);
}
}
return null;
})}
</ul>
</div>
</div>
)}
{followerPopup && (
<div classNameName="popup-profil-container">
<div classNameName="modal">
<h3>Abonnés</h3>
<span classNameName="cross" onClick={() => setFollowerPopup(false)}>
&#10005;
</span>
<ul>
{usersData.map((user) => {
for (let i = 0; i < userData.followers.length; i++) {
if (user._id === userData.followers[i]) {
return (
<li key={user._id}>
<img src={user.picture} alt="user-pic" />
<h4>{user.pseudo}</h4>
<div classNameName="follow-handler">
<FollowHandler idToFollow={user._id} type={'card'} />
</div>
</li>
);
}
}
return null;
})}
</ul>
</div>
</div>
)}
</div>
</div>
</div>
</div>
</main> */}
<main>
<div>

@ -0,0 +1,74 @@
import React, { useState } from 'react';
import axios from 'axios';
import { useParams } from 'react-router-dom';
const ResetPassword = () => {
let { token } = useParams();
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
if (password !== confirmPassword) {
setErrorMessage("Les mots de passe ne correspondent pas");
return;
}
console.log(token);
axios({
method: "post",
url:`${process.env.REACT_APP_API_URL}api/user/reset/${token}`,
withCredentials: true,
data: {
password,
},
})
.then((res) => {
if(res.data.errors){
setErrorMessage(res.data.errors.password);
} else {
window.location = "/";
}
})
.catch((err) => {
console.log(err);
})
};
return (
<div className='formulaire'>
<form className='cadre' action='' onSubmit={handleSubmit}>
<h1>Réinitialisation de mot de passe</h1>
<div className='inputbox'>
<span>Nouveau mot de passe</span>
<input
type="password"
name="password"
id="password"
onChange={(e) => setPassword (e.target.value)}
value={password}
/>
</div>
<br />
<div className='inputbox'>
<span>Confirmer le nouveau mot de passe</span>
<input
type="password"
name="confirmPassword"
id="confirmPassword"
onChange={(e) => setConfirmPassword (e.target.value)}
value={confirmPassword}
/>
</div>
<br />
<input type="submit" value="Réinitialiser le mot de passe" id='connexion' />
<br />
{errorMessage && <h4 className='error'>{errorMessage}</h4>}
</form>
</div>
);
};
export default ResetPassword;

@ -26,7 +26,6 @@ $color-10:#dddddd;
padding: 0;
margin: 0;
box-sizing: border-box;
max-height: 100%;
}
body{

@ -25,7 +25,7 @@
transition: all 1s;
}
.active-btn{
background: $color-8;
background: $color-2;
&:hover {
background: $color-5;
@ -41,7 +41,6 @@
}
.profile-page{
@ -58,8 +57,110 @@
.description-type-connection{
text-align: center;
padding-top: 10px;
}
.popup-conditions {
position: fixed;
animation: popup 1s forwards;
z-index: 100;
left: 50%;
width: 500px;
h3{
padding-bottom: 20px;
font-size: 30px;
}
@keyframes popup {
from{
backdrop-filter: none;
}
to {
backdrop-filter: blur(2px);
}
}
p{
line-height: 30px;
line-clamp: 20px;
font-size: 15px;
}
.modal {
transform: translate(-100%);
background: $color-2;
padding: 25px;
border-radius: 20px;
box-shadow: 0 0 2px rgba(131, 130, 130, 0.356);
overflow: auto;
transform: scaleY(0);
transform-origin: center;
animation: modal .5s forwards;
h3 {
min-width: 200px;
}
@keyframes modal {
to {
transform: scale(1) translate(-50%);
}
}
.cross {
position: absolute;
top: 25px;
right: 25px;
transition: 0.1s;
cursor: pointer;
&:hover {
transform: scale(1.07);
}
}
ul {
min-width: 250px;
max-width: 300px;
margin: 20px 0 0;
max-height: 500px;
min-height: 200px;
li {
display: grid;
grid-template-columns: 64px 1fr 114px;
align-items: center;
margin: 10px 0;
img {
height: 50px;
width: 50px;
border-radius: 20px;
object-fit: cover;
box-shadow: 0 0 2px rgba(51, 51, 51, 0.376);
}
h4 {
text-align: left;
min-width: 210px;
}
.follow-handler {
text-align: left;
button {
background: $color-4;
border-radius: 20px;
margin-right: 6px;
&:hover {
color: $color-3;
transform: translateX(2px);
}
}
}
}
}
}
}
.cadre {
@ -147,6 +248,10 @@ input[type="submit"]:hover, .buttonTEL:hover{
}
.info-form-container{
border-radius: 0px 10px 10px 0px;
display: flex;
flex-direction: column;
justify-content: space-between;
.info-form-right{
padding-top: 15px;
}
@ -157,7 +262,7 @@ input[type="submit"]:hover, .buttonTEL:hover{
}
.formulaire{
width: 35%;
width: 40%;
}
/*
@ -174,6 +279,7 @@ input[type="submit"]:hover, .buttonTEL:hover{
.form-presentation{
background-color: aquamarine;
width: 400px;
display: flex;
flex-direction: column;
@ -182,7 +288,30 @@ input[type="submit"]:hover, .buttonTEL:hover{
position: fixed;
border-right: 2px solid black;
border-radius: 5px;
p:first-child{
padding-top: 30%;
}
p{
padding-top: 10%;
padding-top: 5%;
line-height: 1.5;
font-size: 20px;
font-weight: 800;
padding-left: 30px;
padding-right: 30px;
text-align: center;
}
img{
padding-top: 20px;
}
}
.imginsc{
border-radius: 0px 10px 10px 0px;
}
.cond{
text-decoration : underline;
font-weight: bolder;
cursor: pointer;
}

@ -1,9 +1,10 @@
const UserModel = require('../models/user.model');
const jwt = require('jsonwebtoken');
const nodemailer = require('nodemailer');
const { signUpErrors, signInErrors } = require('../utils/errors.utils');
const crypto = require('crypto');
//const nodemailer = require('nodemailer');
const maxAge = 3 * 24 * 60 * 60 * 1000;
//expiresIn temps avant l'expiration du token
const createToken = (id) => {
return jwt.sign({id}, process.env.TOKEN_SECRET, {
@ -12,17 +13,16 @@ const createToken = (id) => {
}
// // Définir les informations de connexion pour le service d'envoi d'e-mails
// const transporter = nodemailer.createTransport({
// service: 'gmail',
// auth: {
// user: 'mixmox07340@gmail.com',
// pass: 'Appwow07'
// }
// });
// Définir les informations de connexion pour le service d'envoi d'e-mails
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'mixmox07340@gmail.com',
pass: 'Appwow07'
}
});
// module.exports.signUp = async (req, res) => {
// console.log(req.body);
// const {pseudo, email, password} = req.body
@ -51,23 +51,139 @@ const createToken = (id) => {
// res.status(200).send({ errors })
// }
// }
// module.exports.verifyEmail = async (req, res) => {
// const { email, token } = req.body;
// try {
// // Vérifier le jeton de vérification
// jwt.verify(token, 'secret-key', async (err, decoded) => {
// if (err) {
// return res.status(401).json({ error: 'Jeton de vérification non valide' });
// }
// if (decoded.email){
// }
// })
// }catch(err){
// }
// };
module.exports.sendVerificationEmail = async (req, res) => {
try {
const { email } = req.body;
// Générer un jeton de vérification
const verificationToken = jwt.sign({ email }, 'secret-key', { expiresIn: '24h' });
// Préparer l'e-mail de vérification
const mailOptions = {
from: 'your-email@gmail.com',
to: email,
subject: 'Vérifiez votre adresse e-mail',
html: `
<p>Veuillez cliquer sur le lien ci-dessous pour vérifier votre adresse e-mail :</p>
<a href="http://your-website.com/verify-email?token=${verificationToken}">Cliquez ici pour vérifier</a>
`
};
// Envoyer l'e-mail de vérification
await transporter.sendMail(mailOptions);
res.json({ verificationToken });
} catch (error) {
console.error(error);
res.status(500).json({ error });
}
};
module.exports.forgotPassword = async (req, res) => {
const { email } = req.body;
UserModel.findOne({ email })
.then(user => {
if (!user) {
res.status(404).json({ message: "Aucun utilisateur n'a été trouvé avec cette adresse email" });
} else {
// Génération d'un jeton de réinitialisation de mot de passe
const token = crypto.randomBytes(20).toString('hex');
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 heure
user.save()
.then(() => {
// Envoi d'un email avec le lien de réinitialisation de mot de passe
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'mixmox07340@gmail.com',
pass: 'fnvepgdxfscstdzl'
}
});
console.log("test5");
const mailOptions = {
from: 'mixmox07340@gmail.com',
to: email,
subject: 'Réinitialisation de mot de passe',
text: `Pour réinitialiser votre mot de passe, veuillez cliquer sur ce lien : http://localhost:3000/reset/${token}`
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.log(error);
res.status(500).json({ message: "Une erreur est survenue lors de l'envoi de l'email de réinitialisation de mot de passe" });
} else {
console.log('Email sent: ' + info.response);
res.status(200).json({ message: "Un email de réinitialisation de mot de passe a été envoyé à l'adresse email spécifiée" });
}
});
});
}
})
.catch(err => {
res.status(500).json({ message: "Une erreur est survenue lors de la recherche de l'utilisateur" });
});
};
module.exports.resetGet = async (req, res) => {
UserModel.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } })
.then(user => {
if (!user) {
res.status(404).json({ message: "Le lien de réinitialisation de mot de passe est soit expiré ou invalide" });
} else {
// Affichez une page HTML pour saisir un nouveau mot de passe
res.status(200).send("Veuillez saisir votre nouveau mot de passe");
}
})
.catch(err => {
res.status(500).json({ message: "Une erreur est survenue lors de la vérification du jeton de réinitialisation de mot de passe" });
})};
module.exports.resetPost = async (req, res) => {
console.log("test");
UserModel.findOneAndUpdate({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } })
.then(user => {
if (!user) {
res.status(404).json({ message: "Le lien de réinitialisation de mot de passe est soit expiré ou invalide" });
} else {
// Modifiez le mot de passe de l'utilisateur et enregistrez-le dans la base de données
user.password = req.body.password;
console.log(req.body.password);
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
// user.save()
// .then(() => {
res.status(200).json({ message: "Mot de passe réinitialisé avec succès" });
// })
// .catch(err => {
// res.status(500).json({ message: "Une erreur est survenue lors de la mise à jour du mot de passe" });
// });
}
})
.catch(err => {
res.status(500).json({ message: "Une erreur est survenue lors de la vérification du jeton de réinitialisation de mot de passe" });
});
};
module.exports.verifyEmail = async (req, res) => {
try {
const { email, token } = req.body;
// Vérifier le jeton de vérification
jwt.verify(token, 'secret-key', async (err, decoded) => {
if (err) {
return res.status(401).json({ error: 'Jeton de vérification non valide' });
}
if (decoded.email !== email) {
return res.status(401).json({ error: 'Adresse e-mail non valide' });
}
// Marquer l'adresse e-mail comme vérifiée dans la base de données
const updateResponse = await User.updateOne({ email }, { isVerified: true });
if (!updateResponse.nModified) {
return res.status(404).json({ error: 'Adresse e-mail non trouvée' });
}
res.json({ isVerified: true });
});
} catch (error) {
console.error(error);
res.status(500).json({ error: "une erreur s'est produte lors de la vérification de l'adresse e-mail" });
}
};
//gestion des erreurs
module.exports.signUp = async (req, res) => {

File diff suppressed because it is too large Load Diff

@ -16,10 +16,19 @@
"body-parser": "^1.20.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"crypto": "^1.0.1",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"forwarded": "^0.2.0",
"has-flag": "^5.0.1",
"ip": "^1.1.8",
"ipaddr.js": "^2.0.1",
"is-fullwidth-code-point": "^4.0.0",
"js-cookie": "^3.0.1",
"jsonwebtoken": "^8.5.1",
"lru-cache": "^7.14.1",
"mailgun-js": "^0.22.0",
"media-typer": "^1.1.0",
"mongoose": "^6.6.6",
"multer": "^1.4.5-lts.1",
"nodemailer": "^6.9.0",
@ -29,8 +38,13 @@
"react-router-dom": "^6.6.1",
"react-scripts": "^5.0.1",
"sass": "^1.57.1",
"smart-buffer": "^4.2.0",
"string-width": "^5.1.2",
"supports-color": "^9.3.1",
"tachyons": "^4.12.0",
"tr46": "^3.0.0",
"validator": "^13.7.0",
"web-vitals": "^3.1.0"
"web-vitals": "^3.1.0",
"webidl-conversions": "^7.0.0"
}
}

@ -25,6 +25,11 @@ router.patch('/notif/:id', userController.getNotif);
router.patch('/:id/image', userController.saveImage);
router.get('/:id/image',userController.getImage);
router.put('/update/:id',userController.compteUpdatePseudo);
router.post('/verify-email',authController.verifyEmail);
router.post('/forgotpassword',authController.forgotPassword);
router.post('/reset/:token',authController.resetPost);
router.get('/reset/:token',authController.resetGet);
router.post('/send-verification-email',authController.sendVerificationEmail);
//upload pb avec postman
//router.post("/upload", upload.single('file'), uploadController.uploadProfil);

Loading…
Cancel
Save