Confirm and password emails sending
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
CREATE TABLE raid_builder.raid_instance_person_character_xref(
|
||||
raid_instance_person_character_xref_id uuid PRIMARY KEY,
|
||||
raid_instance_id uuid REFERENCES raid_builder.raid_instance(raid_instance_id) NOT NULL,
|
||||
person_character_id uuid REFERENCES raid_builder.person_character(person_character_id) NOT NULL,
|
||||
person_character_id uuid REFERENCES raid_builder.person_character(person_character_id),
|
||||
group_number int NOT NULL,
|
||||
position_number int NOT NULL,
|
||||
|
||||
|
||||
12
pom.xml
12
pom.xml
@@ -140,6 +140,18 @@
|
||||
<artifactId>disruptor</artifactId>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--! Email -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.angus</groupId>
|
||||
<artifactId>angus-mail</artifactId>
|
||||
<version>2.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -46,8 +46,8 @@ public class SecurityConfig{
|
||||
auth.requestMatchers(HttpMethod.OPTIONS).permitAll()
|
||||
.requestMatchers("/icons/**").permitAll()
|
||||
.requestMatchers("/auth/refresh", "/auth/test").permitAll() //Permit refresh tokens
|
||||
.requestMatchers(HttpMethod.POST, "/auth/signup", "/auth/confirm").permitAll() //Permit signup operations
|
||||
.requestMatchers("/auth/forgot", "/auth/forgot/*").permitAll() //Permit forgot password operations
|
||||
.requestMatchers(HttpMethod.POST, "/auth/signup", "/auth/confirm/*").permitAll() //Permit signup operations
|
||||
.requestMatchers(HttpMethod.POST, "/auth/forgot", "/auth/forgot/*").permitAll() //Permit forgot password operations
|
||||
.anyRequest().authenticated();
|
||||
})
|
||||
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
|
||||
|
||||
@@ -27,7 +27,9 @@ import com.mattrixwv.raidbuilder.entity.Account;
|
||||
import com.mattrixwv.raidbuilder.service.AccountService;
|
||||
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType;
|
||||
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountStatus;
|
||||
import com.mattrixwv.raidbuilder.util.EmailUtil;
|
||||
|
||||
import jakarta.mail.internet.InternetAddress;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@@ -44,6 +46,8 @@ public class AuthenticationController{
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final TokenService tokenService;
|
||||
private final AccountService accountService;
|
||||
//Email
|
||||
private final EmailUtil emailUtil;
|
||||
|
||||
|
||||
@GetMapping("/token")
|
||||
@@ -121,8 +125,6 @@ public class AuthenticationController{
|
||||
returnNode.put("accountId", account.getAccountId().toString());
|
||||
returnNode.put("status", "success");
|
||||
|
||||
//TODO: Send email
|
||||
|
||||
log.info("Successfully created account: {}", account.getAccountId());
|
||||
}
|
||||
else{
|
||||
@@ -136,10 +138,9 @@ public class AuthenticationController{
|
||||
return returnNode;
|
||||
}
|
||||
|
||||
@PostMapping("/confirm")
|
||||
@PostMapping("/confirm/{confirmToken}")
|
||||
@AccountAuthorization(permissions = {})
|
||||
public ObjectNode confirm(@RequestBody ObjectNode confirmNode){
|
||||
UUID confirmToken = UUID.fromString(confirmNode.get("confirmToken").asText());
|
||||
public ObjectNode confirm(@PathVariable("confirmToken") UUID confirmToken){
|
||||
log.info("Confirming account with token {}", confirmToken);
|
||||
|
||||
|
||||
@@ -164,14 +165,14 @@ public class AuthenticationController{
|
||||
|
||||
@PostMapping("/forgot")
|
||||
@AccountAuthorization(permissions = {})
|
||||
public ObjectNode forgot(@RequestParam("loginId") String loginId){
|
||||
log.info("Setting up user that forgot their password: {}", loginId);
|
||||
public ObjectNode forgot(@RequestParam("username") String username){
|
||||
log.info("Setting up user that forgot their password: {}", username);
|
||||
|
||||
|
||||
ObjectNode returnNode = mapper.createObjectNode();
|
||||
|
||||
//Verify the account exists
|
||||
Account account = accountService.getByUsername(loginId);
|
||||
Account account = accountService.getByUsername(username);
|
||||
if(account != null){
|
||||
//Setup token
|
||||
UUID token = UUID.randomUUID();
|
||||
@@ -181,24 +182,29 @@ public class AuthenticationController{
|
||||
|
||||
account = accountService.updateAccount(account);
|
||||
|
||||
//TODO: Send email
|
||||
try{
|
||||
emailUtil.sendPasswordResetEmail(new InternetAddress(account.getEmail()), token);
|
||||
}
|
||||
catch(Exception error){
|
||||
log.error("Error sending email", error);
|
||||
throw new RuntimeException("Error sending reset email", error);
|
||||
}
|
||||
|
||||
returnNode.put("status", "success");
|
||||
}
|
||||
else{
|
||||
ArrayNode errorsNode = mapper.createArrayNode();
|
||||
errorsNode.add("Could not find account with login " + loginId);
|
||||
errorsNode.add("Could not find account with login " + username);
|
||||
returnNode.set("errors", errorsNode);
|
||||
}
|
||||
|
||||
return returnNode;
|
||||
}
|
||||
|
||||
@PostMapping("/forgot/reset")
|
||||
@PostMapping("/forgot/{forgotToken}")
|
||||
@AccountAuthorization(permissions = {})
|
||||
public ObjectNode setNewPasswordForgot(@RequestBody ObjectNode forgotNode){
|
||||
UUID forgotToken = UUID.fromString(forgotNode.get("forgotToken").asText());
|
||||
String newPassword = forgotNode.get("password").asText();
|
||||
public ObjectNode setNewPasswordForgot(@PathVariable("forgotToken") UUID forgotToken, @RequestBody ObjectNode passwordNode){
|
||||
String newPassword = passwordNode.get("password").asText();
|
||||
log.info("Confirming user reset password (forget) with token {}", forgotToken);
|
||||
|
||||
|
||||
|
||||
@@ -23,11 +23,15 @@ import com.mattrixwv.raidbuilder.repository.account.AccountRepository;
|
||||
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType;
|
||||
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountStatus;
|
||||
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.TutorialStatus;
|
||||
import com.mattrixwv.raidbuilder.util.EmailUtil;
|
||||
import com.mattrixwv.raidbuilder.util.UserPrincipal;
|
||||
|
||||
import jakarta.mail.internet.InternetAddress;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@RequiredArgsConstructor
|
||||
@@ -39,6 +43,8 @@ public class AccountService implements UserDetailsService{
|
||||
private final AccountPermissionService accountPermissionService;
|
||||
private final GamePermissionService gamePermissionService;
|
||||
private final RaidGroupPermissionService raidGroupPermissionService;
|
||||
//Emails
|
||||
private final EmailUtil emailUtil;
|
||||
//Fields
|
||||
@Value("${jwt.refreshTokenDuration}")
|
||||
private Duration refreshTokenDuration;
|
||||
@@ -71,6 +77,16 @@ public class AccountService implements UserDetailsService{
|
||||
accountTutorialStatus.setInstanceTutorialStatus(TutorialStatus.NOT_COMPLETED);
|
||||
accountTutorialStatus = accountTutorialStatusService.createAccountTutorialStatus(accountTutorialStatus);
|
||||
|
||||
|
||||
//Send confirmation email
|
||||
try{
|
||||
emailUtil.sendConfirmationEmail(new InternetAddress(account.getEmail()), account.getRefreshToken());
|
||||
}
|
||||
catch(Exception error){
|
||||
log.error(error.getMessage(), error);
|
||||
throw new RuntimeException("Could not send confirmation email", error);
|
||||
}
|
||||
|
||||
//Return the new account
|
||||
return account;
|
||||
}
|
||||
|
||||
74
src/main/java/com/mattrixwv/raidbuilder/util/EmailUtil.java
Normal file
74
src/main/java/com/mattrixwv/raidbuilder/util/EmailUtil.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package com.mattrixwv.raidbuilder.util;
|
||||
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.mail.Message;
|
||||
import jakarta.mail.MessagingException;
|
||||
import jakarta.mail.Session;
|
||||
import jakarta.mail.Transport;
|
||||
import jakarta.mail.internet.InternetAddress;
|
||||
import jakarta.mail.internet.MimeMessage;
|
||||
|
||||
|
||||
@Component
|
||||
public class EmailUtil{
|
||||
@Value("${email.username}")
|
||||
private String username;
|
||||
@Value("${email.password}")
|
||||
private String password;
|
||||
@Value("${email.from}")
|
||||
private InternetAddress fromAddress;
|
||||
|
||||
|
||||
public Session createSession(){
|
||||
Properties props = new Properties();
|
||||
props.put("mail.smtp.host", "smtp.gmail.com");
|
||||
props.put("mail.smtp.port", "465");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
props.put("mail.smtp.socketFactory.port", "465");
|
||||
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
||||
|
||||
return Session.getInstance(props, new jakarta.mail.Authenticator(){
|
||||
@Override
|
||||
protected jakarta.mail.PasswordAuthentication getPasswordAuthentication(){
|
||||
return new jakarta.mail.PasswordAuthentication(username, password);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void sendConfirmationEmail(InternetAddress toAddress, UUID confirmationToken) throws MessagingException{
|
||||
sendMessage(
|
||||
createSession(),
|
||||
toAddress,
|
||||
fromAddress,
|
||||
"Raid Builder Confirmation",
|
||||
"<p>This is the confirmation email for your Raid Builder Account.<br/><a href=https://raidbuilder.mattrixwv.com/confirm/" + confirmationToken.toString() + ">Click Here</a> to confirm your account.</p>"
|
||||
);
|
||||
}
|
||||
|
||||
public void sendPasswordResetEmail(InternetAddress toAddress, UUID resetToken) throws MessagingException{
|
||||
sendMessage(
|
||||
createSession(),
|
||||
toAddress,
|
||||
fromAddress,
|
||||
"Raid Builder Password Reset",
|
||||
"<p>This is the password reset email for your Raid Builder Account.<br/><a href=https://raidBuilder.mattrixwv.com/forgotPassword/" + resetToken.toString() + ">Click Here</a> to reset your password.</p>"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public static void sendMessage(Session session, InternetAddress toAddress, InternetAddress fromAddress, String subject, String body) throws MessagingException{
|
||||
MimeMessage message = new MimeMessage(session);
|
||||
message.setFrom(fromAddress);
|
||||
message.setRecipient(Message.RecipientType.TO, toAddress);
|
||||
message.setSubject(subject);
|
||||
message.setText(body, "utf-8", "html");
|
||||
|
||||
Transport.send(message);
|
||||
}
|
||||
}
|
||||
@@ -23,3 +23,9 @@ jwt.refreshTokenDuration=30d
|
||||
#Files
|
||||
uploadFileDirectory=../raidBuilderIcons
|
||||
spring.servlet.multipart.max-file-size=10MB
|
||||
|
||||
|
||||
#Email
|
||||
email.username=
|
||||
email.password=
|
||||
email.from=
|
||||
|
||||
Reference in New Issue
Block a user