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

This commit is contained in:
Braydon 2024-09-18 18:23:18 -04:00
parent 29f0d39a78
commit a929a4ee48
6 changed files with 49 additions and 21 deletions

@ -2,7 +2,7 @@ name: Deploy API
on:
push:
branches: ["master"]
branches: [ "master" ]
paths-ignore:
- README.md
- LICENSE
@ -11,8 +11,8 @@ jobs:
deploy:
strategy:
matrix:
arch: ["ubuntu-latest"]
git-version: ["2.44.0"]
arch: [ "ubuntu-latest" ]
git-version: [ "2.44.0" ]
runs-on: ${{ matrix.arch }}
# Steps to run

@ -18,7 +18,7 @@ public final class StringUtils {
private static final SecureRandom RANDOM = new SecureRandom();
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.

@ -1,9 +1,9 @@
package cc.pulseapp.api.controller.v1;
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.UserRegistrationInput;
import cc.pulseapp.api.model.user.response.UserAuthResponse;
import cc.pulseapp.api.service.AuthService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.NonNull;
@ -39,11 +39,11 @@ public final class AuthController {
*
* @param request the http request
* @param input the registration input
* @return the session for the registered user
* @return the user auth response
* @throws BadRequestException if the registration fails
*/
@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));
}
@ -52,11 +52,11 @@ public final class AuthController {
*
* @param request the http request
* @param input the login input
* @return the session for the login user
* @return the user auth response
* @throws BadRequestException if the login fails
*/
@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));
}
}

@ -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.model.Feature;
import cc.pulseapp.api.model.IGenericResponse;
import cc.pulseapp.api.model.user.Session;
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.*;
import cc.pulseapp.api.model.user.input.UserLoginInput;
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.UserRepository;
import jakarta.servlet.http.HttpServletRequest;
@ -64,11 +62,11 @@ public final class AuthService {
*
* @param request the http request
* @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
*/
@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
if (!Feature.USER_REGISTRATION_ENABLED.isEnabled()) {
throw new BadRequestException(Error.REGISTRATION_DISABLED);
@ -83,11 +81,12 @@ public final class AuthService {
// Create the user and return it
byte[] salt = HashUtils.generateSalt();
Date now = new Date();
return generateSession(request, userRepository.save(new User(
User user = userRepository.save(new User(
snowflakeService.generateSnowflake(), input.getEmail(), input.getUsername().toLowerCase(),
HashUtils.hash(salt, input.getPassword()), Base64.getEncoder().encodeToString(salt),
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 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
*/
@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
// 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);
}
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;
import cc.pulseapp.api.common.EnvironmentUtils;
import cc.pulseapp.api.exception.impl.BadRequestException;
import cc.pulseapp.api.model.IGenericResponse;
import com.google.gson.JsonObject;
@ -33,7 +34,7 @@ public final class CaptchaService {
.header(HttpHeaders.CONTENT_TYPE, "application/json")
.body(body)
.asJson();
if (!response.getBody().getObject().getBoolean("success")) {
if (EnvironmentUtils.isProduction() && !response.getBody().getObject().getBoolean("success")) {
throw new BadRequestException(Error.CAPTCHA_INVALID);
}
}