Skip to content
This repository has been archived by the owner on Dec 31, 2023. It is now read-only.

Commit

Permalink
Merge pull request #59 from hardingadonis/vuong_change_password_page
Browse files Browse the repository at this point in the history
Vương: Change password page
  • Loading branch information
GoldStarPro authored Dec 4, 2023
2 parents b6d320f + 3b18112 commit be7a2f6
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.hardingadonis.miu.controller.web;

import io.hardingadonis.miu.model.*;
import io.hardingadonis.miu.services.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;

@WebServlet(name = "ChangePasswordServlet", urlPatterns = {"/change-password"})
public class ChangePasswordServlet extends HttpServlet {

private static final String CHANGE_PASSWORD_SUCCESS_PARAM = "changePasswordSuccess";

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");

User user = (User) request.getSession().getAttribute("user");

if (user == null) {
response.sendRedirect("login");
return;
}

request.getRequestDispatcher("/view/web/change-password.jsp").forward(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");

String hashedCurrentPassword = Hash.SHA256(request.getParameter("current-password"));
String hashedNewPassword = Hash.SHA256(request.getParameter("new-password"));

User user = (User) request.getSession().getAttribute("user");

if (!user.getHashedPassword().equals(hashedCurrentPassword)) {
request.setAttribute("error_msg", "Sai mật khẩu!");
} else if (hashedCurrentPassword.equals(hashedNewPassword)) {
request.setAttribute("error_msg", "Mật khẩu mới không được trùng với mật khẩu cũ!");
} else {
user.setHashedPassword(hashedNewPassword);
Singleton.userDAO.update(user);

request.getSession(false).invalidate();
response.sendRedirect("login?" + CHANGE_PASSWORD_SUCCESS_PARAM + "=true");

return;
}

this.doGet(request, response);
}
}
17 changes: 17 additions & 0 deletions src/main/webapp/assets/css/web/change-password.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.option {
transition: background-color 0.3s;
}

.option:hover {
background-color: #d1d8e0;
}

.option:active {
background-color: rgba(109, 121, 134, 0.9);
color: #ffffff;
}

.option-selected {
background-color: rgba(165, 175, 185, 0.9);
color: #ffffff;
}
63 changes: 63 additions & 0 deletions src/main/webapp/assets/js/web/changePasswordHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const form = document.getElementById('change-password-form');
const currentPasswordInput = document.getElementById('current-password');
const newPasswordInput = document.getElementById('new-password');
const confirmNewPasswordInput = document.getElementById('confirm-new-password');
const errorMessage = document.getElementById('error-message');

form.addEventListener('submit', function (event) {
event.preventDefault();

if (!isStrongPassword(newPasswordInput.value)) {
errorMessage.textContent = 'Mật khẩu mới phải có ít nhất 6 ký tự, trong đó có ít nhất 1 chữ số, 1 chữ cái viết hoa, 1 ký tự đặc biệt!';
newPasswordInput.focus();
return;
}

if (!isPasswordMatch(newPasswordInput.value, confirmNewPasswordInput.value)) {
errorMessage.textContent = 'Mật khẩu mới không khớp!';
confirmNewPasswordInput.focus();
return;
}

this.submit();
});

currentPasswordInput.addEventListener('input', function () {
removeSpaces(currentPasswordInput);
});

newPasswordInput.addEventListener('input', function () {
removeSpaces(newPasswordInput);
});

confirmNewPasswordInput.addEventListener('input', function () {
removeSpaces(confirmNewPasswordInput);
});

function removeSpaces(input) {
input.value = input.value.replace(/\s/g, '');
}

function isPasswordMatch(password, confirmPassword) {
return password === confirmPassword;
}

function isStrongPassword(password) {
if (password.length < 6) {
return false;
}

if (!/\d/.test(password)) {
return false;
}

if (!/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/-]/.test(password)) {
return false;
}

if (!/[A-Z]/.test(password)) {
return false;
}

return true;
}
78 changes: 78 additions & 0 deletions src/main/webapp/view/web/change-password.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<%@ page contentType="text/html" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>

<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" />
<link rel="stylesheet" href="<%=request.getContextPath()%>/assets/css/web/common/common.css" />
<link rel="stylesheet" href="<%=request.getContextPath()%>/assets/css/web/change-password.css" />

<link rel="icon" type="image/x-icon" href="<%=request.getContextPath()%>/assets/images/favicon/favicon.png">

<title>Miu Shop | Đổi mật khẩu</title>
</head>

<body>
<%@include file="common/_header.jsp" %>

<section class="py-5 my-5">
<div class="container">
<div class="row">
<div class="col-lg-3 col-sm-12 text-center">
<img src="./${sessionScope.user.avatarPath}" alt="Avatar" class="img-thumbnail rounded">
<h3 class="my-4">${sessionScope.user.fullName}</h3>
<ul class="nav flex-column">
<li class="nav-item">
<a href="profile" class="nav-link text-muted option">Thông tin chung</a>
<a href="delivery-address" class="nav-link text-muted option">Địa chỉ giao hàng</a>
<a href="purchase-history" class="nav-link text-muted option">Lịch sử mua hàng</a>
<a href="change-password" class="nav-link text-muted option option-selected">Đổi mật khẩu</a>
</li>
</ul>
</div>

<div class="col-lg-9 col-sm-12">
<div class="container-fluid p-3 border border-dark">
<h6 class="m-3 text-center display-6">Thay đổi mật khẩu</h6>

<form id="change-password-form" action="change-password" method="post" class="px-5">
<div class="mb-3">
<label for="current-password" class="form-label">Mật khẩu hiện tại</label>
<input name="current-password" class="form-control" type="password" id="current-password" required>
</div>

<div class="mb-3">
<label for="new-password" class="form-label">Mật khẩu mới</label>
<input name="new-password" type="password" class="form-control" id="new-password" required>
</div>

<div class="mb-3">
<label for="confirm-new-password" class="form-label">Xác nhận mật khẩu mới</label>
<input name="confirm-new-password" class="form-control" type="password" id="confirm-new-password" required>
</div>

<div class="my-3 text-center">
<div id="error-message" class="text-danger my-3">${error_msg}</div>
<button type="submit" class="btn btn-outline-dark">Xác Nhận</button>
</div>
</form>
</div>
</div>
</div>
</div>
</section>

<%@include file="common/_footer.jsp" %>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="<%=request.getContextPath()%>/assets/js/web/common/commonHandler.js"></script>
<script src="<%=request.getContextPath()%>/assets/js/web/changePasswordHandler.js"></script>
</body>

</html>
14 changes: 14 additions & 0 deletions src/main/webapp/view/web/login.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@
</div>
</c:if>

<%-- Kiểm tra xem có URL parameter changePasswordSuccess hay không --%>
<c:if test="${param.changePasswordSuccess == 'true'}">
<style>
.main {
min-height: 75vh;
padding-bottom: 8.5vh;
}
</style>

<div class="alert alert-success mx-auto" role="alert" style="max-width: 500px;">
Bạn đã đổi mật khẩu thành công. Vui lòng đăng nhập để tiếp tục.
</div>
</c:if>

<div class="container main">
<div class="row">
<div class="col-md-6 side-image">
Expand Down

0 comments on commit be7a2f6

Please sign in to comment.