mirror of
https://github.com/kmitresse/Cards-Rush.git
synced 2026-07-09 13:27:45 +00:00
feat: devWeb - update reset password page
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
package uppa.project.bean;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.Date;
|
||||||
|
import uppa.project.database.dao.DAO;
|
||||||
|
import uppa.project.database.dao.DAOException;
|
||||||
|
import uppa.project.database.dao.EntityManagerProvider;
|
||||||
|
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
|
||||||
|
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||||
|
import uppa.project.database.pojo.User;
|
||||||
|
|
||||||
|
public class ResetPasswordBean implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
private String password;
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
public ResetPasswordBean() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResetPasswordBean(String token, String password) {
|
||||||
|
this.token = token;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validate() {
|
||||||
|
Game_JPA_DAO_Factory jpaDaoFactory = new Game_JPA_DAO_Factory();
|
||||||
|
DAO<User> userDAO;
|
||||||
|
DAO<RecoveryPasswordToken> recoveryPasswordTokenDAO;
|
||||||
|
|
||||||
|
// Check if the user is valid
|
||||||
|
EntityManager entityManager = EntityManagerProvider.getInstance();
|
||||||
|
entityManager.getTransaction().begin();
|
||||||
|
try {
|
||||||
|
userDAO = jpaDaoFactory.getDAOUser();
|
||||||
|
recoveryPasswordTokenDAO = jpaDaoFactory.getDAORecoveryPasswordToken();
|
||||||
|
|
||||||
|
// Check if the token is valid
|
||||||
|
RecoveryPasswordToken[] tokens = recoveryPasswordTokenDAO.findByField("token", token);
|
||||||
|
if (tokens.length == 0) {
|
||||||
|
errorMessage = "Ce token n'est pas valide";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RecoveryPasswordToken token = tokens[0];
|
||||||
|
|
||||||
|
//Recuperer l'utilisateur associé au token
|
||||||
|
User user = token.getUser();
|
||||||
|
if (user == null) {
|
||||||
|
errorMessage = "Erreur: Aucun utilisateur associé à ce token";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
user.setPassword(password);
|
||||||
|
|
||||||
|
userDAO.update(user);
|
||||||
|
entityManager.getTransaction().commit();
|
||||||
|
} catch (DAOException e) {
|
||||||
|
errorMessage = "Une erreur est survenue (DB_CONNECTION_ERROR)";
|
||||||
|
entityManager.getTransaction().rollback();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResetPasswordBean setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResetPasswordBean setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,22 @@
|
|||||||
package uppa.project.web.servlet;
|
package uppa.project.web.servlet;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
import jakarta.servlet.annotation.WebServlet;
|
||||||
import jakarta.servlet.http.HttpServlet;
|
import jakarta.servlet.http.HttpServlet;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import uppa.project.bean.RegisterBean;
|
||||||
|
import uppa.project.bean.ResetPasswordBean;
|
||||||
import uppa.project.database.dao.DAOException;
|
import uppa.project.database.dao.DAOException;
|
||||||
import uppa.project.database.dao.jpa.DAO_JPA_RecoveryPasswordToken;
|
import uppa.project.database.dao.jpa.DAO_JPA_RecoveryPasswordToken;
|
||||||
import uppa.project.database.dao.jpa.DAO_JPA_User;
|
import uppa.project.database.dao.jpa.DAO_JPA_User;
|
||||||
import uppa.project.database.pojo.RecoveryPasswordToken;
|
import uppa.project.database.pojo.RecoveryPasswordToken;
|
||||||
import uppa.project.database.pojo.User;
|
import uppa.project.database.pojo.User;
|
||||||
|
import uppa.project.json.HttpResponse;
|
||||||
|
import uppa.project.json.HttpResponseCode;
|
||||||
|
|
||||||
@WebServlet(name = "resetPasswordServlet", value = "/reset-password")
|
@WebServlet(name = "resetPasswordServlet", value = "/reset-password")
|
||||||
public class ResetPasswordServlet extends HttpServlet {
|
public class ResetPasswordServlet extends HttpServlet {
|
||||||
@@ -20,11 +26,11 @@ public class ResetPasswordServlet extends HttpServlet {
|
|||||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
|
||||||
RecoveryPasswordToken token = findRecoveryToken(request.getParameter("token"));
|
RecoveryPasswordToken token = findRecoveryToken(request.getParameter("token"));
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
response.sendRedirect(request.getContextPath() + "/forgotten-password?error=invalid-token");
|
request.getRequestDispatcher("/WEB-INF/pages/invalid-token-password.jsp").forward(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (token.getExpirationDate().compareTo(new java.util.Date()) < 0){
|
if (token.getExpirationDate().compareTo(new java.util.Date()) < 0){
|
||||||
response.sendRedirect(request.getContextPath() + "/forgotten-password?error=expired-token");
|
request.getRequestDispatcher("/WEB-INF/pages/expired-token-password.jsp").forward(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request.setAttribute("current", "reset-password");
|
request.setAttribute("current", "reset-password");
|
||||||
@@ -39,28 +45,28 @@ public class ResetPasswordServlet extends HttpServlet {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
RecoveryPasswordToken recoveryPasswordToken = findRecoveryToken(request.getParameter("token"));
|
response.setContentType("application/json");
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
PrintWriter out = response.getWriter();
|
||||||
|
|
||||||
User user = recoveryPasswordToken.getUser();
|
ResetPasswordBean resetPasswordBean = new ResetPasswordBean()
|
||||||
String newPassword = request.getParameter("newPassword");
|
.setToken(request.getParameter("token"))
|
||||||
String confirmPassword = request.getParameter("confirmPassword");
|
.setPassword(request.getParameter("password"))
|
||||||
System.out.println("newPassword: " + newPassword);
|
;
|
||||||
System.out.println("confirmPassword: " + confirmPassword);
|
|
||||||
System.out.println(!newPassword.equals(confirmPassword));
|
Gson gson = new Gson();
|
||||||
if (!newPassword.equals(confirmPassword)) {
|
HttpResponse httpResponse;
|
||||||
System.out.println("ici");
|
if (resetPasswordBean.validate()) {
|
||||||
response.sendRedirect(request.getContextPath() + "/reset-password?error=matching-password&token=" + recoveryPasswordToken.getToken());
|
httpResponse = new HttpResponse(
|
||||||
return;
|
HttpResponseCode.OK,
|
||||||
}
|
"Register success"
|
||||||
user.setPassword(newPassword);
|
);
|
||||||
DAO_JPA_User daoJpaUser = null;
|
} else {
|
||||||
try {
|
httpResponse = new HttpResponse(HttpResponseCode.INTERNAL_SERVER_ERROR, resetPasswordBean.getErrorMessage());
|
||||||
daoJpaUser = new DAO_JPA_User();
|
|
||||||
daoJpaUser.update(user);
|
|
||||||
response.sendRedirect(request.getContextPath() + "/login?success=password-reseted");
|
|
||||||
} catch (DAOException e) {
|
|
||||||
response.sendRedirect(request.getContextPath() + "/reset-password?error=1");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out.println(gson.toJson(httpResponse));
|
||||||
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecoveryPasswordToken findRecoveryToken(String token) {
|
public static RecoveryPasswordToken findRecoveryToken(String token) {
|
||||||
|
|||||||
@@ -1,27 +1,22 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
|
||||||
<html>
|
<%@taglib prefix="layout" tagdir="/WEB-INF/tags/layouts" %>
|
||||||
<head>
|
<%@taglib prefix="form" tagdir="/WEB-INF/tags/forms" %>
|
||||||
<title>Récupération du mot de passe</title>
|
<layout:base>
|
||||||
<meta charset="UTF-8">
|
<jsp:attribute name="title">Cards Rush - Récuperation mot de passe</jsp:attribute>
|
||||||
<%-- <link href="${pageContext.request.contextPath}/static/css/reset-password.css" rel="stylesheet">--%>
|
<jsp:body>
|
||||||
<script src="${pageContext.request.contextPath}/static/js/reset-password.js" defer></script>
|
<div class="hero is-light is-fullheight-with-navbar">
|
||||||
</head>
|
<div class="hero-body">
|
||||||
<body>
|
<div class="container">
|
||||||
<%@include file="../components/navbar.jsp"%>
|
<div class="columns is-centered">
|
||||||
<main>
|
<div class="column is-5-tablet is-5-desktop is-5-widescreen">
|
||||||
<jsp:include page="../components/navbar.jsp"/>
|
<div class="box">
|
||||||
<h1>Récupération du mot de passe</h1>
|
<h1 class="title has-text-centered">Récupération de mot de passe</h1>
|
||||||
<form id="resetPasswordForm" action="${pageContext.request.contextPath}/reset-password" method="post">
|
<form:reset-password/>
|
||||||
<label for="newPassword">Nouveau mot de passe</label>
|
</div>
|
||||||
<input type="password" id="newPassword" name="newPassword" required>
|
</div>
|
||||||
<label for="confirmPassword">Confirmer le mot de passe</label>
|
</div>
|
||||||
<input type="password" id="confirmPassword" name="confirmPassword" required>
|
</div>
|
||||||
<% if (request.getParameter("error") != null && request.getParameter("error").equals("matching-password")) {%>
|
</div>
|
||||||
<p>Les mots de passe ne correspondent pas</p>
|
</div>
|
||||||
<% } %>
|
</jsp:body>
|
||||||
<input type="hidden" name="token" value="${param.token}">
|
</layout:base>
|
||||||
<input type="submit" value="Valider">
|
|
||||||
</form>
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
<%@tag description="form/register" pageEncoding="UTF-8" %>
|
||||||
|
|
||||||
|
<form id="reset-password-form" action="${pageContext.request.contextPath}/reset-password" method="post">
|
||||||
|
<input type="hidden" id="token" name="token" value="${pageContext.request.getParameter("token")}">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="password">Mot de passe</label>
|
||||||
|
<input id="password" name="password" type="password" class="input is-fullwidth" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="repassword">Confirmez le mot de passe</label>
|
||||||
|
<input id="repassword" name="repassword" type="password" class="input is-fullwidth" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="button is-primary is-fullwidth" value="Envoyer">
|
||||||
|
<hr/>
|
||||||
|
<p class="content has-text-centered">Déjà inscrit ? <a href="${pageContext.request.contextPath}/login">Se connecter</a></p>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.notification {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 1em !important;
|
||||||
|
max-width: 40em;
|
||||||
|
|
||||||
|
transform: translateY(100%);
|
||||||
|
opacity: 0;
|
||||||
|
animation: toast 5s ease forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes toast {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
|
5% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
95% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script defer type="module">
|
||||||
|
const resetPasswordForm = document.querySelector("form#reset-password-form");
|
||||||
|
const submitButton = document.querySelector("input[type=submit]");
|
||||||
|
|
||||||
|
// Form fields
|
||||||
|
const tokenInput = document.querySelector("input#token");
|
||||||
|
const passwordInput = document.querySelector("input#password");
|
||||||
|
const repasswordInput = document.querySelector("input#repassword");
|
||||||
|
|
||||||
|
// Add event listener to the form submission
|
||||||
|
resetPasswordForm.addEventListener("submit", onSubmit)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the form submission with Ajax request
|
||||||
|
* @param event {Event} - Event of the form submission
|
||||||
|
*/
|
||||||
|
function onSubmit(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Check if the password and the confirmation password are the same
|
||||||
|
if (passwordInput.value !== repasswordInput.value) {
|
||||||
|
onError(new Error("Les mots de passe ne correspondent pas"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {action, method} = resetPasswordForm;
|
||||||
|
|
||||||
|
const url = new URL(action);
|
||||||
|
url.searchParams.append("token", tokenInput.value);
|
||||||
|
url.searchParams.append("password", passwordInput.value);
|
||||||
|
|
||||||
|
submitButton.classList.add("is-loading");
|
||||||
|
fetch(url, {headers: {"Content-Type": "application/json"}, method})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.code !== 200) throw new Error(data.message);
|
||||||
|
})
|
||||||
|
.then(() => window.location.href = "${pageContext.request.contextPath}/login")
|
||||||
|
.catch(onError)
|
||||||
|
.finally(() => submitButton.classList.remove("is-loading"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the error of the form submission
|
||||||
|
* @param error {Error} - Error of the form submission
|
||||||
|
*/
|
||||||
|
function onError(error) {
|
||||||
|
console.error("Error:", error)
|
||||||
|
|
||||||
|
// Input fields in red
|
||||||
|
passwordInput.classList.add("is-danger");
|
||||||
|
repasswordInput.classList.add("is-danger");
|
||||||
|
|
||||||
|
// Notification
|
||||||
|
const notification = document.createElement("div");
|
||||||
|
notification.classList.add("notification", "is-danger");
|
||||||
|
notification.innerHTML = error.message;
|
||||||
|
document.body.appendChild(notification);
|
||||||
|
setTimeout(() => notification.remove(), 5010);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
Reference in New Issue
Block a user