return the user as well as the session when authenticating
All checks were successful
Deploy API / deploy (ubuntu-latest, 2.44.0) (push) Successful in 41s
All checks were successful
Deploy API / deploy (ubuntu-latest, 2.44.0) (push) Successful in 41s
This commit is contained in:
parent
29f0d39a78
commit
a929a4ee48
@ -2,7 +2,7 @@ name: Deploy API
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ["master"]
|
branches: [ "master" ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- README.md
|
- README.md
|
||||||
- LICENSE
|
- LICENSE
|
||||||
@ -11,8 +11,8 @@ jobs:
|
|||||||
deploy:
|
deploy:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
arch: ["ubuntu-latest"]
|
arch: [ "ubuntu-latest" ]
|
||||||
git-version: ["2.44.0"]
|
git-version: [ "2.44.0" ]
|
||||||
runs-on: ${{ matrix.arch }}
|
runs-on: ${{ matrix.arch }}
|
||||||
|
|
||||||
# Steps to run
|
# Steps to run
|
||||||
|
@ -18,7 +18,7 @@ public final class StringUtils {
|
|||||||
private static final SecureRandom RANDOM = new SecureRandom();
|
private static final SecureRandom RANDOM = new SecureRandom();
|
||||||
|
|
||||||
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)$");
|
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)$");
|
||||||
private static final Pattern USERNAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_.]*$");
|
private static final Pattern USERNAME_PATTERN = Pattern.compile("^[a-z0-9_.]*$");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given email is valid.
|
* Check if the given email is valid.
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package cc.pulseapp.api.controller.v1;
|
package cc.pulseapp.api.controller.v1;
|
||||||
|
|
||||||
import cc.pulseapp.api.exception.impl.BadRequestException;
|
import cc.pulseapp.api.exception.impl.BadRequestException;
|
||||||
import cc.pulseapp.api.model.user.Session;
|
|
||||||
import cc.pulseapp.api.model.user.input.UserLoginInput;
|
import cc.pulseapp.api.model.user.input.UserLoginInput;
|
||||||
import cc.pulseapp.api.model.user.input.UserRegistrationInput;
|
import cc.pulseapp.api.model.user.input.UserRegistrationInput;
|
||||||
|
import cc.pulseapp.api.model.user.response.UserAuthResponse;
|
||||||
import cc.pulseapp.api.service.AuthService;
|
import cc.pulseapp.api.service.AuthService;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
@ -39,11 +39,11 @@ public final class AuthController {
|
|||||||
*
|
*
|
||||||
* @param request the http request
|
* @param request the http request
|
||||||
* @param input the registration input
|
* @param input the registration input
|
||||||
* @return the session for the registered user
|
* @return the user auth response
|
||||||
* @throws BadRequestException if the registration fails
|
* @throws BadRequestException if the registration fails
|
||||||
*/
|
*/
|
||||||
@PostMapping("/register") @ResponseBody @NonNull
|
@PostMapping("/register") @ResponseBody @NonNull
|
||||||
public ResponseEntity<Session> register(@NonNull HttpServletRequest request, UserRegistrationInput input) throws BadRequestException {
|
public ResponseEntity<UserAuthResponse> register(@NonNull HttpServletRequest request, UserRegistrationInput input) throws BadRequestException {
|
||||||
return ResponseEntity.ok(authService.registerUser(request, input));
|
return ResponseEntity.ok(authService.registerUser(request, input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,11 +52,11 @@ public final class AuthController {
|
|||||||
*
|
*
|
||||||
* @param request the http request
|
* @param request the http request
|
||||||
* @param input the login input
|
* @param input the login input
|
||||||
* @return the session for the login user
|
* @return the user auth response
|
||||||
* @throws BadRequestException if the login fails
|
* @throws BadRequestException if the login fails
|
||||||
*/
|
*/
|
||||||
@PostMapping("/login") @ResponseBody @NonNull
|
@PostMapping("/login") @ResponseBody @NonNull
|
||||||
public ResponseEntity<Session> login(@NonNull HttpServletRequest request, UserLoginInput input) throws BadRequestException {
|
public ResponseEntity<UserAuthResponse> login(@NonNull HttpServletRequest request, UserLoginInput input) throws BadRequestException {
|
||||||
return ResponseEntity.ok(authService.loginUser(request, input));
|
return ResponseEntity.ok(authService.loginUser(request, input));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package cc.pulseapp.api.model.user.response;
|
||||||
|
|
||||||
|
import cc.pulseapp.api.model.user.Session;
|
||||||
|
import cc.pulseapp.api.model.user.UserDTO;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The response for successfully logging in.
|
||||||
|
*
|
||||||
|
* @author Braydon
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor @Getter @ToString
|
||||||
|
public final class UserAuthResponse {
|
||||||
|
/**
|
||||||
|
* The created session for the user.
|
||||||
|
*/
|
||||||
|
@NonNull private final Session session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user logging in.
|
||||||
|
*/
|
||||||
|
@NonNull private final UserDTO user;
|
||||||
|
}
|
@ -7,12 +7,10 @@ import cc.pulseapp.api.exception.impl.BadRequestException;
|
|||||||
import cc.pulseapp.api.exception.impl.ResourceNotFoundException;
|
import cc.pulseapp.api.exception.impl.ResourceNotFoundException;
|
||||||
import cc.pulseapp.api.model.Feature;
|
import cc.pulseapp.api.model.Feature;
|
||||||
import cc.pulseapp.api.model.IGenericResponse;
|
import cc.pulseapp.api.model.IGenericResponse;
|
||||||
import cc.pulseapp.api.model.user.Session;
|
import cc.pulseapp.api.model.user.*;
|
||||||
import cc.pulseapp.api.model.user.User;
|
|
||||||
import cc.pulseapp.api.model.user.UserFlag;
|
|
||||||
import cc.pulseapp.api.model.user.UserTier;
|
|
||||||
import cc.pulseapp.api.model.user.input.UserLoginInput;
|
import cc.pulseapp.api.model.user.input.UserLoginInput;
|
||||||
import cc.pulseapp.api.model.user.input.UserRegistrationInput;
|
import cc.pulseapp.api.model.user.input.UserRegistrationInput;
|
||||||
|
import cc.pulseapp.api.model.user.response.UserAuthResponse;
|
||||||
import cc.pulseapp.api.repository.SessionRepository;
|
import cc.pulseapp.api.repository.SessionRepository;
|
||||||
import cc.pulseapp.api.repository.UserRepository;
|
import cc.pulseapp.api.repository.UserRepository;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
@ -64,11 +62,11 @@ public final class AuthService {
|
|||||||
*
|
*
|
||||||
* @param request the http request
|
* @param request the http request
|
||||||
* @param input the registration input
|
* @param input the registration input
|
||||||
* @return the registered user's auth token
|
* @return the user auth response
|
||||||
* @throws BadRequestException if the input has an error
|
* @throws BadRequestException if the input has an error
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public Session registerUser(@NonNull HttpServletRequest request, UserRegistrationInput input) throws BadRequestException {
|
public UserAuthResponse registerUser(@NonNull HttpServletRequest request, UserRegistrationInput input) throws BadRequestException {
|
||||||
// Ensure user registration is enabled
|
// Ensure user registration is enabled
|
||||||
if (!Feature.USER_REGISTRATION_ENABLED.isEnabled()) {
|
if (!Feature.USER_REGISTRATION_ENABLED.isEnabled()) {
|
||||||
throw new BadRequestException(Error.REGISTRATION_DISABLED);
|
throw new BadRequestException(Error.REGISTRATION_DISABLED);
|
||||||
@ -83,11 +81,12 @@ public final class AuthService {
|
|||||||
// Create the user and return it
|
// Create the user and return it
|
||||||
byte[] salt = HashUtils.generateSalt();
|
byte[] salt = HashUtils.generateSalt();
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
return generateSession(request, userRepository.save(new User(
|
User user = userRepository.save(new User(
|
||||||
snowflakeService.generateSnowflake(), input.getEmail(), input.getUsername().toLowerCase(),
|
snowflakeService.generateSnowflake(), input.getEmail(), input.getUsername().toLowerCase(),
|
||||||
HashUtils.hash(salt, input.getPassword()), Base64.getEncoder().encodeToString(salt),
|
HashUtils.hash(salt, input.getPassword()), Base64.getEncoder().encodeToString(salt),
|
||||||
null, UserTier.FREE, 0, now
|
null, UserTier.FREE, 0, now
|
||||||
)));
|
));
|
||||||
|
return new UserAuthResponse(generateSession(request, user), UserDTO.asDTO(user, now));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,11 +94,11 @@ public final class AuthService {
|
|||||||
*
|
*
|
||||||
* @param request the http request
|
* @param request the http request
|
||||||
* @param input the login input
|
* @param input the login input
|
||||||
* @return the logged in user's auth token
|
* @return the user auth response
|
||||||
* @throws BadRequestException if the input has an error
|
* @throws BadRequestException if the input has an error
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public Session loginUser(@NonNull HttpServletRequest request, UserLoginInput input) throws BadRequestException {
|
public UserAuthResponse loginUser(@NonNull HttpServletRequest request, UserLoginInput input) throws BadRequestException {
|
||||||
validateLoginInput(input); // Ensure the input is valid
|
validateLoginInput(input); // Ensure the input is valid
|
||||||
|
|
||||||
// Lookup the user by the email or username and ensure the user exists
|
// Lookup the user by the email or username and ensure the user exists
|
||||||
@ -112,7 +111,9 @@ public final class AuthService {
|
|||||||
throw new BadRequestException(Error.PASSWORDS_DO_NOT_MATCH);
|
throw new BadRequestException(Error.PASSWORDS_DO_NOT_MATCH);
|
||||||
}
|
}
|
||||||
user.setLastLogin(new Date());
|
user.setLastLogin(new Date());
|
||||||
return generateSession(request, userRepository.save(user));
|
user = userRepository.save(user);
|
||||||
|
return new UserAuthResponse(generateSession(request, user),
|
||||||
|
UserDTO.asDTO(user, new Date(snowflakeService.extractCreationTime(user.getSnowflake()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cc.pulseapp.api.service;
|
package cc.pulseapp.api.service;
|
||||||
|
|
||||||
|
import cc.pulseapp.api.common.EnvironmentUtils;
|
||||||
import cc.pulseapp.api.exception.impl.BadRequestException;
|
import cc.pulseapp.api.exception.impl.BadRequestException;
|
||||||
import cc.pulseapp.api.model.IGenericResponse;
|
import cc.pulseapp.api.model.IGenericResponse;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
@ -33,7 +34,7 @@ public final class CaptchaService {
|
|||||||
.header(HttpHeaders.CONTENT_TYPE, "application/json")
|
.header(HttpHeaders.CONTENT_TYPE, "application/json")
|
||||||
.body(body)
|
.body(body)
|
||||||
.asJson();
|
.asJson();
|
||||||
if (!response.getBody().getObject().getBoolean("success")) {
|
if (EnvironmentUtils.isProduction() && !response.getBody().getObject().getBoolean("success")) {
|
||||||
throw new BadRequestException(Error.CAPTCHA_INVALID);
|
throw new BadRequestException(Error.CAPTCHA_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user