diff --git a/app/routers/password.py b/app/routers/password.py index d45d22c..6feb88c 100644 --- a/app/routers/password.py +++ b/app/routers/password.py @@ -3,8 +3,9 @@ from fastapi.templating import Jinja2Templates from ..dependencies import users_token, database, mail from ..models import users, email from fastapi.responses import JSONResponse, HTMLResponse -from fastapi_mail import MessageSchema, MessageType, FastMail -import random, os +from fastapi_mail import MessageSchema, MessageType, FastMail +import random, os + router = APIRouter() # Assurer que le chemin vers "templates" est correct @@ -19,6 +20,7 @@ async def forgot_password(userSingle: users.UserForgotPassword): detail="Email is required" ) + # Recherche de l'utilisateur dans la base de données user_repository = users.UserRepository(database=database.database) user = user_repository.find_one_by({"email": {"$eq": userSingle.email}}) @@ -28,35 +30,45 @@ async def forgot_password(userSingle: users.UserForgotPassword): detail="User not found" ) - # Génération d'un token temporaire + # Génération d'un token temporaire pour réinitialisation reset_token = str(random.randint(100000, 999999)) key_hashed = users_token.get_password_hash(reset_token) - email_body = {"key": reset_token, "username": user.username} - email_schema = email.EmailSchema(email=[user.email], body=email_body) + # Créer le lien de réinitialisation + reset_link = f"https://votresite.com/password/reset?key={reset_token}&email={user.email}" + + # Préparer les données à envoyer au template + email_body = { + "username": user.username, + "reset_link": reset_link + } + + # Créer le message à envoyer message = MessageSchema( subject="Password Reset Request", - recipients=email_schema.dict().get("email"), - template_body=email_schema.dict().get("body"), + recipients=[user.email], + template_body=email_body, subtype=MessageType.html, ) + # Utilisation de FastMail pour envoyer l'email fm = FastMail(mail.conf) - await fm.send_message(message, template_name="reset_password.html") + await fm.send_message(message, template_name="forgot_password_email.html") - # Stockage du token temporaire dans Redis avec une expiration - database.connect_redis.setex(user.email, 3600, key_hashed) # Expire dans 1 heure + # Stockage du token temporaire dans Redis avec une expiration d'1 heure + database.connect_redis.setex(user.email, 3600, key_hashed) return JSONResponse(status_code=status.HTTP_200_OK, content={"message": "Password reset email has been sent"}) @router.get("/password/reset", tags=["password"]) async def reset_password(request: Request, key: str | None = None, email: str | None = None): - if key is None or email is None: + if not key or not email: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, - detail="Parameter key or/and email is empty" + detail="Parameters 'key' and 'email' are required" ) + # Vérifier que la clé correspond à celle stockée dans Redis key_hashed = database.connect_redis.get(email) if key_hashed is None or key_hashed.decode() != key: @@ -65,6 +77,7 @@ async def reset_password(request: Request, key: str | None = None, email: str | detail="Key is invalid or expired" ) + # Afficher la page HTML de réinitialisation du mot de passe return templates.TemplateResponse("reset_password.html", {"request": request, "email": email, "key": key}) @router.post("/password/update", tags=["password"]) @@ -95,5 +108,5 @@ async def update_password(email: str = Form(...), key: str = Form(...), new_pass # Suppression du token temporaire dans Redis database.connect_redis.delete(email) - # Renvoyer une réponse HTML après la mise à jour réussie + # Afficher un message de succès dans une réponse HTML return templates.TemplateResponse("password_update_success.html", {"request": request, "email": email}) diff --git a/app/templates/forgot_password_email.html b/app/templates/forgot_password_email.html new file mode 100644 index 0000000..9291baf --- /dev/null +++ b/app/templates/forgot_password_email.html @@ -0,0 +1,69 @@ + + + + + + + Réinitialisation de votre mot de passe + + + +
+

Demande de réinitialisation du mot de passe

+

Bonjour {{ username }},

+

Nous avons reçu une demande pour réinitialiser votre mot de passe sur notre site. Si vous n'êtes pas à l'origine de cette demande, vous pouvez ignorer cet email.

+

Pour réinitialiser votre mot de passe, cliquez sur le lien ci-dessous :

+

Réinitialiser mon mot de passe

+

Le lien est valable pendant une heure. Si vous ne pouvez pas cliquer dessus, copiez et collez-le dans votre navigateur.

+
+ + + + diff --git a/app/templates/reset_password.html b/app/templates/reset_password.html new file mode 100644 index 0000000..6c1f1c1 --- /dev/null +++ b/app/templates/reset_password.html @@ -0,0 +1,87 @@ + + + + + + Réinitialisation du mot de passe + + + +
+

Réinitialisation du mot de passe

+ +
+ + + +
+ + +
+ + +
+ +
+

Vous avez des questions ? Contactez-nous

+
+
+ +