Skip to content

Commit

Permalink
Merge branch 'main' into SCRUM-95
Browse files Browse the repository at this point in the history
  • Loading branch information
Hsbalazs authored Sep 18, 2024
2 parents d3c7247 + f6ad2ea commit 929e83a
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.greenfoxacademy.backend.config;

import com.greenfoxacademy.backend.errors.CannotSendEmailException;
import com.greenfoxacademy.backend.errors.CannotUpdateUserException;
import com.greenfoxacademy.backend.errors.CannotVerifyUserError;
import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError;
import com.greenfoxacademy.backend.errors.UserAlreadyExistsError;
import java.util.HashMap;
Expand Down Expand Up @@ -81,4 +83,34 @@ public ResponseEntity<?> handleUnableToDeleteProfileError(UnableToDeleteProfileE
errors.put("error", "Unable to delete profile");
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
}

/**
* Handle UnableToDeleteProfileError error globally in controllers.
*
* @param ex UnableToDeleteProfileError instance
*
* @return ResponseEntity with BAD_REQUEST and error key-value pair
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(CannotSendEmailException.class)
public ResponseEntity<?> handleCannotSendEmail(CannotSendEmailException ex) {
HashMap<String, String> errors = new HashMap<>();
errors.put("error", ex.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
}

/**
* Handle UserNotVerifiedException error globally in controllers.
*
* @param ex UserNotVerifiedException instance
*
* @return ResponseEntity with BAD_REQUEST and error key-value pair
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(CannotVerifyUserError.class)
public ResponseEntity<?> handleVerifyUser(CannotVerifyUserError ex) {
HashMap<String, String> errors = new HashMap<>();
errors.put("error", ex.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.greenfoxacademy.backend.errors.CannotUpdateUserException;
import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError;
import com.greenfoxacademy.backend.errors.UserAlreadyExistsError;
import com.greenfoxacademy.backend.errors.UserNotVerifiedException;
import com.greenfoxacademy.backend.services.user.owner.OwnerService;
import java.security.Principal;
import java.util.UUID;
Expand Down Expand Up @@ -55,12 +56,9 @@ public ResponseEntity<RegisterResponseDto> registerUser(
* @return a response entity with the status code and the token
*/
@PostMapping("/login")
public ResponseEntity<LoginResponseDto> loginUser(@RequestBody LoginRequestDto loginRequestDto) {
try {
public ResponseEntity<LoginResponseDto> loginUser(@RequestBody LoginRequestDto loginRequestDto)
throws UserNotVerifiedException {
return ResponseEntity.status(HttpStatus.OK).body(ownerService.login(loginRequestDto));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.greenfoxacademy.backend.errors;

/**
* Error to throw when a user cannot be verified.
* <p>
* This error should be thrown when a user cannot be verified.
* </p>
*/
public class CannotSendEmailException extends RuntimeException {
public CannotSendEmailException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.greenfoxacademy.backend.errors;

/**
* Error to throw when a user cannot be verified.
* <p>
* This error should be thrown when a user cannot be verified.
* </p>
*/
public class UserNotVerifiedException extends RuntimeException {
public UserNotVerifiedException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.greenfoxacademy.backend.errors.CannotVerifyUserError;
import com.greenfoxacademy.backend.errors.UnableToDeleteProfileError;
import com.greenfoxacademy.backend.errors.UserAlreadyExistsError;
import com.greenfoxacademy.backend.errors.UserNotVerifiedException;
import com.greenfoxacademy.backend.models.Owner;
import java.util.UUID;
import org.springframework.security.core.userdetails.UserDetails;
Expand All @@ -28,7 +29,8 @@ public interface OwnerService extends UserDetailsService {

RegisterResponseDto register(RegisterRequestDto userDto) throws UserAlreadyExistsError;

LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception;
LoginResponseDto login(LoginRequestDto loginRequestDto)
throws UserNotVerifiedException, UsernameNotFoundException;

ProfileUpdateResponseDto profileUpdate(
String user,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.greenfoxacademy.backend.dtos.RegisterRequestDto;
import com.greenfoxacademy.backend.dtos.RegisterResponseDto;
import com.greenfoxacademy.backend.errors.CannotUpdateUserException;
import com.greenfoxacademy.backend.errors.CannotVerifyUserError;
import com.greenfoxacademy.backend.errors.UserAlreadyExistsError;
import com.greenfoxacademy.backend.models.Owner;
import com.greenfoxacademy.backend.repositories.OwnerRepository;
Expand Down Expand Up @@ -65,13 +66,15 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto)
}

@Override
public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception {
public LoginResponseDto login(LoginRequestDto loginRequestDto) throws
CannotVerifyUserError,
UsernameNotFoundException {
Owner owner = ownerRepository.findByEmail(loginRequestDto.email())
.orElseThrow(() -> new Exception("User not found"));
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
if (!owner.isEnabled()) {
throw new Exception("User's email is not verified");
throw new CannotVerifyUserError("User's email is not verified");
} else if (!passwordEncoder.matches(loginRequestDto.password(), owner.getPassword())) {
throw new Exception("Invalid password");
throw new UsernameNotFoundException("Invalid password");
}
return new LoginResponseDto(authService.generateToken(owner));
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 26 additions & 21 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,32 @@ import { ProtectedPage } from "./pages/utils/ProtectedPage";
const router = createBrowserRouter([
{
path: "/",
element: <Main />,
},
{
path: "register",
element: <Register />,
},
{
path: "login",
element: <Login />,
},
{
path: "profile-update",
element: <ProfileUpdate />,
},
{
path: "profile",
element: <ProfileDetail />,
},
{
path: "delete-profile",
element: <ProfileDeletion />,
children: [
{
path: "/",
element: <Main />,
},
{
path: "register",
element: <Register />,
},
{
path: "login",
element: <Login />,
},
{
path: "profile-update",
element: <ProfileUpdate />,
},
{
path: "profile",
element: <ProfileDetail />,
},
{
path: "delete-profile",
element: <ProfileDeletion />,
},
],
},
{
path: "pets",
Expand Down
9 changes: 5 additions & 4 deletions frontend/src/pages/utils/ProtectedPage.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import type { PropsWithChildren } from "react";
import { Navigate } from "react-router-dom";
import { usePetClinicState } from "../../state";
import { Login } from "../Login";

type ProtectedPageProps = PropsWithChildren;

const ProtectedPage = ({ children }: ProtectedPageProps) => {
const {
auth: { user },
} = usePetClinicState();
if (!user) {
return <Navigate to="/login" />;
if (user) {
return <>{children}</>;
}
return <>{children}</>;
return <Login />;
};
export { ProtectedPage };

0 comments on commit 929e83a

Please sign in to comment.