optimize account creation and verification

This commit is contained in:
Krrish Ghimire
2026-07-10 15:11:20 +05:45
parent bbd6e6d007
commit a3f9cef883
14 changed files with 135 additions and 60 deletions

View File

@@ -2,7 +2,6 @@ package com.krrishg.dto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Data
@@ -11,11 +10,4 @@ public class RegisterRequest {
@NotBlank(message = "Email is required")
@Email(message = "Invalid email format")
private String email;
@NotBlank(message = "Password is required")
@Size(min = 8, max = 100, message = "Password must be between 8 and 100 characters")
private String password;
@NotBlank(message = "Name is required")
private String name;
}

View File

@@ -16,4 +16,7 @@ public class SetPasswordRequest {
@NotBlank
@Size(min = 8, max = 100)
private String password;
@NotBlank(message = "Name is required")
private String name;
}

View File

@@ -29,7 +29,7 @@ public class User {
@Column(name = "password")
private String password;
@Column(name = "name", nullable = false)
@Column(name = "name")
private String name;
@Column(name = "avatar_url")

View File

@@ -69,8 +69,6 @@ public class AuthService {
User user = User.builder()
.email(email)
.password(passwordEncoder.encode(request.getPassword()))
.name(request.getName())
.emailVerified(false)
.build();
@@ -88,12 +86,12 @@ public class AuthService {
User user = userRepository.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("Invalid email or password"));
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
throw new IllegalArgumentException("Invalid email or password");
if (!user.isEmailVerified() || user.getPassword() == null) {
throw new IllegalArgumentException("Please verify your email address before logging in");
}
if (!user.isEmailVerified()) {
throw new IllegalArgumentException("Please verify your email address before logging in");
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
throw new IllegalArgumentException("Invalid email or password");
}
return generateAuthResponse(user);
@@ -174,6 +172,7 @@ public class AuthService {
User user = userRepository.findById(token.getUserId())
.orElseThrow(() -> new IllegalArgumentException("User not found"));
user.setName(request.getName());
user.setPassword(passwordEncoder.encode(request.getPassword()));
userRepository.save(user);

View File

@@ -28,6 +28,7 @@ public class EmailService {
public void sendVerificationEmail(String to, String name, String token) {
String link = baseUrl + "/verify-email?token=" + token;
String displayName = name != null ? name : to.substring(0, to.indexOf('@'));
String subject = "Verify your Indie account";
String html = """
<!DOCTYPE html>
@@ -61,7 +62,7 @@ public class EmailService {
</table>
</body>
</html>
""".formatted(name, link);
""".formatted(displayName, link);
sendHtml(to, subject, html);
}

View File

@@ -68,7 +68,7 @@ indie:
master-key-path: ${INDIE_ENCRYPTION_KEY_PATH:config/encryption.key}
app:
base-url: ${INDIE_APP_BASE_URL:http://localhost:4200}
base-url: ${INDIE_APP_BASE_URL:https://indie.krrishg.com}
verification-token-expiration-minutes: ${INDIE_VERIFICATION_TOKEN_EXPIRATION:1440}
llm:

View File

@@ -52,8 +52,6 @@ class AuthControllerTest {
RegisterRequest request = new RegisterRequest();
request.setEmail("test@example.com");
request.setPassword("password123");
request.setName("Test");
mockMvc.perform(post("/api/auth/register")
.contentType(MediaType.APPLICATION_JSON)
@@ -218,6 +216,7 @@ class AuthControllerTest {
SetPasswordRequest request = new SetPasswordRequest();
request.setSetupToken("setup-token-123");
request.setPassword("new-password");
request.setName("Test");
mockMvc.perform(post("/api/auth/set-password")
.contentType(MediaType.APPLICATION_JSON)
@@ -233,6 +232,7 @@ class AuthControllerTest {
SetPasswordRequest request = new SetPasswordRequest();
request.setSetupToken("bad-token");
request.setPassword("new-password");
request.setName("Test");
mockMvc.perform(post("/api/auth/set-password")
.contentType(MediaType.APPLICATION_JSON)

View File

@@ -43,8 +43,6 @@ class AuthServiceTest {
void registerCreatesUserAndSendsVerification() {
RegisterRequest request = new RegisterRequest();
request.setEmail("new@example.com");
request.setPassword("password123");
request.setName("New User");
RegistrationResponse response = authService.register(request);
@@ -53,12 +51,21 @@ class AuthServiceTest {
assertFalse(userRepository.findByEmail("new@example.com").get().isEmailVerified());
}
@Test
void registerDoesNotSetName() {
RegisterRequest request = new RegisterRequest();
request.setEmail("noname@example.com");
authService.register(request);
User user = userRepository.findByEmail("noname@example.com").get();
assertNull(user.getName());
}
@Test
void registerSendsVerificationEmail() {
RegisterRequest request = new RegisterRequest();
request.setEmail("emailtest@example.com");
request.setPassword("password123");
request.setName("Email Test");
authService.register(request);
@@ -79,8 +86,6 @@ class AuthServiceTest {
RegisterRequest request = new RegisterRequest();
request.setEmail("verified@example.com");
request.setPassword("password123");
request.setName("Should Not Matter");
RegistrationResponse response = authService.register(request);
@@ -100,8 +105,6 @@ class AuthServiceTest {
RegisterRequest request = new RegisterRequest();
request.setEmail("unverified@example.com");
request.setPassword("newpassword");
request.setName("New Name");
RegistrationResponse response = authService.register(request);
@@ -114,8 +117,6 @@ class AuthServiceTest {
void registerNormalizesEmailCase() {
RegisterRequest request = new RegisterRequest();
request.setEmail("UpperCase@Example.com");
request.setPassword("password123");
request.setName("User");
authService.register(request);
@@ -126,11 +127,10 @@ class AuthServiceTest {
void loginWithValidCredentialsAndVerifiedEmailReturnsTokens() {
RegisterRequest reg = new RegisterRequest();
reg.setEmail("login@example.com");
reg.setPassword("password123");
reg.setName("Login User");
authService.register(reg);
User user = userRepository.findByEmail("login@example.com").get();
user.setPassword("{stub}password123");
user.setEmailVerified(true);
userRepository.save(user);
@@ -149,8 +149,6 @@ class AuthServiceTest {
void loginThrowsWhenEmailNotVerified() {
RegisterRequest reg = new RegisterRequest();
reg.setEmail("unverified@example.com");
reg.setPassword("password123");
reg.setName("Unverified");
authService.register(reg);
LoginRequest login = new LoginRequest();
@@ -166,11 +164,10 @@ class AuthServiceTest {
void loginThrowsOnWrongPassword() {
RegisterRequest reg = new RegisterRequest();
reg.setEmail("wrongpw@example.com");
reg.setPassword("correctpw");
reg.setName("User");
authService.register(reg);
User user = userRepository.findByEmail("wrongpw@example.com").get();
user.setPassword("{stub}correctpw");
user.setEmailVerified(true);
userRepository.save(user);
@@ -315,11 +312,13 @@ class AuthServiceTest {
SetPasswordRequest request = new SetPasswordRequest();
request.setSetupToken("setup-token-123");
request.setPassword("new-password");
request.setName("New Name");
authService.setPassword(request);
User updatedUser = userRepository.findById(user.getId()).get();
assertTrue(updatedUser.getPassword().contains("new-password"));
assertEquals("New Name", updatedUser.getName());
VerificationToken updatedToken = tokenRepository.findByToken("verify-token").get();
assertTrue(updatedToken.isSetupTokenUsed());
@@ -480,8 +479,6 @@ class AuthServiceTest {
void refreshTokenReturnsNewTokens() {
RegisterRequest reg = new RegisterRequest();
reg.setEmail("refresh@example.com");
reg.setPassword("password123");
reg.setName("Refresh User");
authService.register(reg);
User user = userRepository.findByEmail("refresh@example.com").get();