├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── src ├── test │ └── java │ │ └── com │ │ └── dailycodework │ │ └── sbend2endapplication │ │ └── SbEnd2endapplicationApplicationTests.java └── main │ ├── resources │ ├── templates │ │ ├── home.html │ │ ├── fragment │ │ │ ├── header.html │ │ │ └── navbar.html │ │ ├── error.html │ │ ├── forgot-password-form.html │ │ ├── update-user.html │ │ ├── users.html │ │ ├── fragments.html │ │ ├── password-reset-form.html │ │ ├── registration.html │ │ └── login.html │ └── application.yml │ └── java │ └── com │ └── dailycodework │ └── sbend2endapplication │ ├── SbEnd2endapplicationApplication.java │ ├── utility │ ├── UrlUtil.java │ └── TokenExpirationTime.java │ ├── registration │ ├── password │ │ ├── PasswordResetTokenRepository.java │ │ ├── IPasswordResetTokenService.java │ │ ├── PasswordResetToken.java │ │ └── PasswordResetTokenService.java │ ├── RegistrationRequest.java │ ├── token │ │ ├── VerificationTokenRepository.java │ │ ├── IVerificationTokenService.java │ │ ├── VerificationToken.java │ │ └── VerificationTokenService.java │ └── RegistrationController.java │ ├── user │ ├── IUserService.java │ ├── Role.java │ ├── UserRepository.java │ ├── User.java │ ├── UserController.java │ └── UserService.java │ ├── event │ ├── RegistrationCompleteEvent.java │ └── listener │ │ └── RegistrationCompleteEventListener.java │ ├── home │ └── HomeController.java │ └── security │ ├── EndToEndUserDetailsService.java │ ├── EndToEndUserDetails.java │ └── EndToEndSecurityDemo.java ├── .gitignore ├── pom.xml ├── mvnw.cmd └── mvnw /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dailycodework/spring-mvc-web-app-with-thymeleaf/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/test/java/com/dailycodework/sbend2endapplication/SbEnd2endapplicationApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.dailycodework.sbend2endapplication; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SbEnd2endapplicationApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |Invalid verification token
15 |This verification link has already expired.
19 |No user found with this email
15 |We have just sent a verification link to your email, please check to complete your request.
19 |You have successfully reset your password, please log in here.
13 |Invalid username or password
14 |You have successfully reset your password, please log in here.
18 |This account has already been verified, please log in here.
22 |Email verified successfully, please log in here.
25 |You have been logged out.
30 |Hi, "+ user.getFirstName()+ ",
"+ 48 | "Thank you for registering with us,"+"" + 49 | "Please, follow the link below to complete your registration.
"+ 50 | "Verify your email to activate your account"+ 51 | " Thank you
Users Registration Portal Service";
52 | emailMessage(subject, senderName, mailContent, mailSender, user);
53 | }
54 |
55 |
56 | public void sendPasswordResetVerificationEmail(String url) throws MessagingException, UnsupportedEncodingException {
57 | String subject = "Password Reset Request Verification";
58 | String senderName = "Users Verification Service";
59 | String mailContent = "
Hi, "+ user.getFirstName()+ ",
"+ 60 | "You recently requested to reset your password,"+"" + 61 | "Please, follow the link below to complete the action.
"+ 62 | "Reset password"+ 63 | " Users Registration Portal Service";
64 | emailMessage(subject, senderName, mailContent, mailSender, user);
65 | }
66 |
67 | private static void emailMessage(String subject, String senderName,
68 | String mailContent, JavaMailSender mailSender, User theUser)
69 | throws MessagingException, UnsupportedEncodingException {
70 | MimeMessage message = mailSender.createMimeMessage();
71 | var messageHelper = new MimeMessageHelper(message);
72 | messageHelper.setFrom("dailycodeworks@gmail.com", senderName);
73 | messageHelper.setTo(theUser.getEmail());
74 | messageHelper.setSubject(subject);
75 | messageHelper.setText(mailContent, true);
76 | mailSender.send(message);
77 | }
78 |
79 |
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/com/dailycodework/sbend2endapplication/registration/RegistrationController.java:
--------------------------------------------------------------------------------
1 | package com.dailycodework.sbend2endapplication.registration;
2 | import com.dailycodework.sbend2endapplication.event.RegistrationCompleteEvent;
3 | import com.dailycodework.sbend2endapplication.event.listener.RegistrationCompleteEventListener;
4 | import com.dailycodework.sbend2endapplication.registration.password.IPasswordResetTokenService;
5 | import com.dailycodework.sbend2endapplication.registration.password.PasswordResetTokenService;
6 | import com.dailycodework.sbend2endapplication.registration.token.VerificationToken;
7 | import com.dailycodework.sbend2endapplication.registration.token.VerificationTokenService;
8 | import com.dailycodework.sbend2endapplication.user.IUserService;
9 | import com.dailycodework.sbend2endapplication.user.User;
10 | import com.dailycodework.sbend2endapplication.utility.UrlUtil;
11 | import jakarta.mail.MessagingException;
12 | import jakarta.servlet.http.HttpServletRequest;
13 | import lombok.RequiredArgsConstructor;
14 | import org.springframework.context.ApplicationEventPublisher;
15 | import org.springframework.stereotype.Controller;
16 | import org.springframework.ui.Model;
17 | import org.springframework.web.bind.annotation.*;
18 |
19 |
20 | import java.io.UnsupportedEncodingException;
21 | import java.util.Optional;
22 | import java.util.UUID;
23 |
24 |
25 | /**
26 | * @author Sampson Alfred
27 | */
28 | @Controller
29 | @RequiredArgsConstructor
30 | @RequestMapping("/registration")
31 | public class RegistrationController {
32 | private final IUserService userService;
33 | private final ApplicationEventPublisher publisher;
34 | private final VerificationTokenService tokenService;
35 | private final IPasswordResetTokenService passwordResetTokenService;
36 | private final RegistrationCompleteEventListener eventListener;
37 |
38 |
39 | @GetMapping("/registration-form")
40 | public String showRegistrationForm(Model model) {
41 | model.addAttribute("user", new RegistrationRequest());
42 | return "registration";
43 | }
44 | @PostMapping("/register")
45 | public String registerUser(@ModelAttribute("user") RegistrationRequest registration, HttpServletRequest request) {
46 | User user = userService.registerUser(registration);
47 | publisher.publishEvent(new RegistrationCompleteEvent(user, UrlUtil.getApplicationUrl(request)));
48 | return "redirect:/registration/registration-form?success";
49 | }
50 | @GetMapping("/verifyEmail")
51 | public String verifyEmail(@RequestParam("token") String token) {
52 | Optional