/user/exists now requires a captcha
All checks were successful
Deploy API / deploy (ubuntu-latest, 2.44.0) (push) Successful in 45s
All checks were successful
Deploy API / deploy (ubuntu-latest, 2.44.0) (push) Successful in 45s
This commit is contained in:
parent
955b035687
commit
f3d5ead017
@ -5,6 +5,7 @@ import cc.pulseapp.api.model.user.User;
|
||||
import cc.pulseapp.api.model.user.UserDTO;
|
||||
import cc.pulseapp.api.model.user.input.CompleteOnboardingInput;
|
||||
import cc.pulseapp.api.model.user.input.EnableTFAInput;
|
||||
import cc.pulseapp.api.model.user.input.UserExistsInput;
|
||||
import cc.pulseapp.api.model.user.response.UserSetupTFAResponse;
|
||||
import cc.pulseapp.api.service.UserService;
|
||||
import lombok.NonNull;
|
||||
@ -50,12 +51,12 @@ public final class UserController {
|
||||
* A GET endpoint to check if a
|
||||
* user exists with the given email.
|
||||
*
|
||||
* @param email the email to check
|
||||
* @param input the input to check
|
||||
* @return the response
|
||||
*/
|
||||
@GetMapping("/exists") @ResponseBody @NonNull
|
||||
public ResponseEntity<Map<String, Object>> doesUserExist(@RequestParam @NonNull String email) {
|
||||
return ResponseEntity.ok(Map.of("exists", userService.doesUserExist(email)));
|
||||
@PostMapping("/exists") @ResponseBody @NonNull
|
||||
public ResponseEntity<Map<String, Object>> doesUserExist(UserExistsInput input) {
|
||||
return ResponseEntity.ok(Map.of("exists", userService.doesUserExist(input)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,35 @@
|
||||
package cc.pulseapp.api.model.user.input;
|
||||
|
||||
import cc.pulseapp.api.model.user.User;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* The input to check if
|
||||
* a {@link User} exists.
|
||||
*
|
||||
* @author Braydon
|
||||
*/
|
||||
@AllArgsConstructor @Getter @ToString
|
||||
public final class UserExistsInput {
|
||||
/**
|
||||
* The email of the user to check.
|
||||
*/
|
||||
private final String email;
|
||||
|
||||
/**
|
||||
* The captcha response token to validate.
|
||||
*/
|
||||
private final String captchaResponse;
|
||||
|
||||
/**
|
||||
* Check if this input is valid.
|
||||
*
|
||||
* @return whether this input is valid
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return email != null && (!email.isBlank())
|
||||
&& captchaResponse != null && (!captchaResponse.isBlank());
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ public final class CaptchaService {
|
||||
.header(HttpHeaders.CONTENT_TYPE, "application/json")
|
||||
.body(body)
|
||||
.asJson();
|
||||
if (EnvironmentUtils.isProduction() && !response.getBody().getObject().getBoolean("success")) {
|
||||
if (/*EnvironmentUtils.isProduction() && */!response.getBody().getObject().getBoolean("success")) {
|
||||
throw new BadRequestException(Error.CAPTCHA_INVALID);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import cc.pulseapp.api.model.user.UserDTO;
|
||||
import cc.pulseapp.api.model.user.UserFlag;
|
||||
import cc.pulseapp.api.model.user.input.CompleteOnboardingInput;
|
||||
import cc.pulseapp.api.model.user.input.EnableTFAInput;
|
||||
import cc.pulseapp.api.model.user.input.UserExistsInput;
|
||||
import cc.pulseapp.api.model.user.response.UserSetupTFAResponse;
|
||||
import cc.pulseapp.api.repository.SessionRepository;
|
||||
import cc.pulseapp.api.repository.UserRepository;
|
||||
@ -56,6 +57,11 @@ public final class UserService {
|
||||
*/
|
||||
@NonNull private final TFAService tfaService;
|
||||
|
||||
/**
|
||||
* The captcha service to use.
|
||||
*/
|
||||
@NonNull private final CaptchaService captchaService;
|
||||
|
||||
/**
|
||||
* The user repository to use.
|
||||
*/
|
||||
@ -80,13 +86,14 @@ public final class UserService {
|
||||
@Autowired
|
||||
public UserService(@NonNull AuthService authService, @NonNull SnowflakeService snowflakeService,
|
||||
@NonNull OrganizationService orgService, @NonNull StatusPageService statusPageService,
|
||||
@NonNull TFAService tfaService, @NonNull UserRepository userRepository,
|
||||
@NonNull SessionRepository sessionRepository) {
|
||||
@NonNull TFAService tfaService, @NonNull CaptchaService captchaService,
|
||||
@NonNull UserRepository userRepository, @NonNull SessionRepository sessionRepository) {
|
||||
this.authService = authService;
|
||||
this.snowflakeService = snowflakeService;
|
||||
this.orgService = orgService;
|
||||
this.statusPageService = statusPageService;
|
||||
this.tfaService = tfaService;
|
||||
this.captchaService = captchaService;
|
||||
this.userRepository = userRepository;
|
||||
this.sessionRepository = sessionRepository;
|
||||
}
|
||||
@ -103,13 +110,18 @@ public final class UserService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user with the given email exists.
|
||||
* Check if a user exists
|
||||
* with the given email.
|
||||
*
|
||||
* @param email the email to check
|
||||
* @param input the input to check
|
||||
* @return whether the user exists
|
||||
*/
|
||||
public boolean doesUserExist(@NonNull String email) {
|
||||
return StringUtils.isValidEmail(email) && userRepository.findByEmailIgnoreCase(email) != null;
|
||||
public boolean doesUserExist(UserExistsInput input) {
|
||||
if (input == null || (!input.isValid())) { // Ensure the input was provided
|
||||
throw new BadRequestException(Error.MALFORMED_USER_EXISTS_INPUT);
|
||||
}
|
||||
captchaService.validateCaptcha(input.getCaptchaResponse());
|
||||
return StringUtils.isValidEmail(input.getEmail()) && userRepository.findByEmailIgnoreCase(input.getEmail()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,6 +227,7 @@ public final class UserService {
|
||||
* User errors.
|
||||
*/
|
||||
private enum Error implements IGenericResponse {
|
||||
MALFORMED_USER_EXISTS_INPUT,
|
||||
MALFORMED_ONBOARDING_INPUT,
|
||||
MALFORMED_ENABLE_TFA_INPUT,
|
||||
ORGANIZATION_SLUG_INVALID,
|
||||
|
Loading…
Reference in New Issue
Block a user