Compare commits
4
Commits
d34a304763
...
NCBACK-9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6797a47df5 | ||
|
|
fade754c7c | ||
|
|
f164370989 | ||
|
|
015f2f516c |
+7
-1
@@ -29,13 +29,19 @@ dependencies {
|
|||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||||
implementation 'org.springframework.security:spring-security-crypto:6.5.3'
|
implementation 'org.springframework.security:spring-security-crypto:6.5.3'
|
||||||
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
|
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
|
||||||
|
implementation 'commons-validator:commons-validator:1.7'
|
||||||
|
|
||||||
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
|
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
|
||||||
|
annotationProcessor 'org.projectlombok:lombok'
|
||||||
|
|
||||||
compileOnly 'org.projectlombok:lombok'
|
compileOnly 'org.projectlombok:lombok'
|
||||||
|
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
|
|
||||||
runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc'
|
runtimeOnly 'com.microsoft.sqlserver:mssql-jdbc'
|
||||||
runtimeOnly 'com.mysql:mysql-connector-j'
|
runtimeOnly 'com.mysql:mysql-connector-j'
|
||||||
runtimeOnly 'org.postgresql:postgresql'
|
runtimeOnly 'org.postgresql:postgresql'
|
||||||
annotationProcessor 'org.projectlombok:lombok'
|
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
testImplementation 'org.mockito:mockito-core:5.3.1'
|
testImplementation 'org.mockito:mockito-core:5.3.1'
|
||||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ru.soune.nocopy.dto;
|
|||||||
public enum MessageCode {
|
public enum MessageCode {
|
||||||
SUCCESS(0, "Operation successful"),
|
SUCCESS(0, "Operation successful"),
|
||||||
REG_EMAIL_EXISTS(1, "Email already registered"),
|
REG_EMAIL_EXISTS(1, "Email already registered"),
|
||||||
|
REG_EMAIL_OR_PHONE_EXISTS(1, "Email or phone already registered"),
|
||||||
INVALID_FIELD(2, "Invalid field"),
|
INVALID_FIELD(2, "Invalid field"),
|
||||||
INVALID_JSON_BODY(2, "Invalid fields in JSON object"),
|
INVALID_JSON_BODY(2, "Invalid fields in JSON object"),
|
||||||
MSG_ID_NOT_FOUND(4, "Message id not found"),
|
MSG_ID_NOT_FOUND(4, "Message id not found"),
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public class User {
|
|||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@Size(min = 11, max = 14)
|
@Size(min = 11, max = 14)
|
||||||
|
@Column(unique = true)
|
||||||
private String phone;
|
private String phone;
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
|
|||||||
@@ -33,13 +33,15 @@ public class RegRequestHandler implements RequestHandler {
|
|||||||
public BaseResponse handle(BaseRequest request) throws ValidationException {
|
public BaseResponse handle(BaseRequest request) throws ValidationException {
|
||||||
RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class);
|
RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class);
|
||||||
|
|
||||||
if (userRepository.existsByEmail(regRequest.getEmail())) {
|
if (userRepository.existsByEmail(regRequest.getEmail()) || userRepository.existsByPhone(regRequest.getPhone())) {
|
||||||
RegAnswer regAnswer = new RegAnswer();
|
RegAnswer regAnswer = new RegAnswer();
|
||||||
regAnswer.setFieldErrors(Arrays.asList(Map.of("email", regRequest.getEmail())));
|
regAnswer.setFieldErrors(Arrays.asList(Map.of("email", regRequest.getEmail())));
|
||||||
|
regAnswer.setFieldErrors(Arrays.asList(Map.of("phone", regRequest.getPhone())));
|
||||||
|
|
||||||
throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(),
|
throw new NotValidFieldException("User already exists with email:" + regRequest.getEmail() + " or phone: " +
|
||||||
new BaseResponse(request.getMsgId(), MessageCode.REG_EMAIL_EXISTS.getCode(),
|
regRequest.getPhone(), new BaseResponse(request.getMsgId(),
|
||||||
MessageCode.REG_EMAIL_EXISTS.getDescription(), regAnswer));
|
MessageCode.REG_EMAIL_OR_PHONE_EXISTS.getCode(),
|
||||||
|
MessageCode.REG_EMAIL_OR_PHONE_EXISTS.getDescription(), regAnswer));
|
||||||
}
|
}
|
||||||
|
|
||||||
BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest");
|
BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest");
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package ru.soune.nocopy.handler.validator;
|
package ru.soune.nocopy.handler.validator;
|
||||||
|
|
||||||
|
import org.apache.commons.validator.routines.DomainValidator;
|
||||||
|
import org.apache.commons.validator.routines.EmailValidator;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
import ru.soune.nocopy.dto.RegRequest;
|
import ru.soune.nocopy.dto.RegRequest;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -52,27 +56,6 @@ public class RegRequestValidator implements Validator {
|
|||||||
errors.rejectValue("fullName", "fullName.invalid.chars",
|
errors.rejectValue("fullName", "fullName.invalid.chars",
|
||||||
"Name can only contain letters, spaces, hyphens and apostrophes");
|
"Name can only contain letters, spaces, hyphens and apostrophes");
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] nameParts = trimmedName.split("\\s+");
|
|
||||||
if (nameParts.length < 2) {
|
|
||||||
errors.rejectValue("fullName", "fullName.missing.parts",
|
|
||||||
"Please enter both first and last name");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < nameParts.length; i++) {
|
|
||||||
String part = nameParts[i];
|
|
||||||
if (part.length() < 2 && part.length() > 0) {
|
|
||||||
errors.rejectValue("fullName", "fullName.part.too.short",
|
|
||||||
"Each name part must be at least 2 characters");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Character.isUpperCase(part.charAt(0))) {
|
|
||||||
errors.rejectValue("fullName", "fullName.capitalization",
|
|
||||||
"Each name part should start with capital letter");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateCompanyName(String companyName, Errors errors) {
|
private void validateCompanyName(String companyName, Errors errors) {
|
||||||
@@ -110,64 +93,24 @@ public class RegRequestValidator implements Validator {
|
|||||||
|
|
||||||
private void validateEmail(String email, Errors errors) {
|
private void validateEmail(String email, Errors errors) {
|
||||||
if (email == null || email.trim().isEmpty()) {
|
if (email == null || email.trim().isEmpty()) {
|
||||||
errors.rejectValue("email", "email.is.empty",
|
errors.rejectValue("email", "email.is.empty", "Email must not be empty");
|
||||||
"Email must not be empty");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String trimmedEmail = email.trim().toLowerCase();
|
String trimmedEmail = email.trim().toLowerCase();
|
||||||
|
|
||||||
if (trimmedEmail.length() > 128) {
|
if (trimmedEmail.length() > 254) {
|
||||||
errors.rejectValue("email", "email.too.long",
|
errors.rejectValue("email", "email.too.long", "Email is too long");
|
||||||
"Email must be less than 128 characters");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!trimmedEmail.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")) {
|
EmailValidator emailValidator = EmailValidator.getInstance(true, true);
|
||||||
errors.rejectValue("email", "email.invalid.format",
|
if (!emailValidator.isValid(trimmedEmail)) {
|
||||||
"Invalid email format");
|
errors.rejectValue("email", "email.invalid", "Invalid email address");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] parts = trimmedEmail.split("@");
|
|
||||||
if (parts.length != 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String localPart = parts[0];
|
|
||||||
String domain = parts[1];
|
|
||||||
|
|
||||||
if (localPart.length() > 64) {
|
|
||||||
errors.rejectValue("email", "email.local.too.long",
|
|
||||||
"Email username too long");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!localPart.matches("^[a-z0-9+_.-]+$")) {
|
|
||||||
errors.rejectValue("email", "email.local.invalid.chars",
|
|
||||||
"Email contains invalid characters");
|
|
||||||
}
|
|
||||||
|
|
||||||
validateEmailDomain(domain, errors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateEmailDomain(String domain, Errors errors) {
|
|
||||||
if (domain.length() > 255) {
|
|
||||||
errors.rejectValue("email", "email.domain.too.long",
|
|
||||||
"Email domain too long");
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] domainParts = domain.split("\\.");
|
|
||||||
if (domainParts.length < 2) {
|
|
||||||
errors.rejectValue("email", "email.domain.invalid",
|
|
||||||
"Invalid domain name");
|
|
||||||
}
|
|
||||||
|
|
||||||
String tld = domainParts[domainParts.length - 1];
|
|
||||||
if (tld.length() < 2) {
|
|
||||||
errors.rejectValue("email", "email.tld.invalid",
|
|
||||||
"Invalid domain extension");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validatePhone(String phone, Errors errors) {
|
private void validatePhone(String phone, Errors errors) {
|
||||||
if (phone == null || phone.trim().isEmpty()) {
|
if (phone == null || phone.trim().isEmpty()) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package ru.soune.nocopy.repository;
|
package ru.soune.nocopy.repository;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import ru.soune.nocopy.entity.User;
|
import ru.soune.nocopy.entity.User;
|
||||||
|
|
||||||
@@ -8,4 +9,5 @@ import java.util.Optional;
|
|||||||
public interface UserRepository extends JpaRepository<User, Long> {
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
Optional<User> findByEmail(String email);
|
Optional<User> findByEmail(String email);
|
||||||
boolean existsByEmail(String email);
|
boolean existsByEmail(String email);
|
||||||
|
boolean existsByPhone(@Size(min = 11, max = 14) String phone);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user