From 5d18da6ebe8a5a8becf0c99e6f9241524c98d5a0 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Fri, 3 Feb 2023 17:05:33 +0100 Subject: [PATCH] Refactored API organization, added functionality for password resets. --- gymboard-api/README.md | 10 ++ gymboard-api/pom.xml | 16 ++- .../gymboard_api/config/SecurityConfig.java | 6 +- .../config/TokenAuthenticationFilter.java | 6 +- .../controller/dto/TokenResponse.java | 3 - .../controller/dto/UserActivationPayload.java | 3 - .../api}/controller/ExerciseController.java | 6 +- .../api}/controller/GymController.java | 14 +-- .../controller/LeaderboardController.java | 6 +- .../api}/controller/SubmissionController.java | 6 +- .../{ => domains/api}/dao/CityRepository.java | 6 +- .../api}/dao/CountryRepository.java | 4 +- .../{ => domains/api}/dao/GymRepository.java | 8 +- .../api}/dao/exercise/ExerciseRepository.java | 4 +- .../ExerciseSubmissionRepository.java | 4 +- .../api}/dto/CompoundGymId.java | 2 +- .../api}/dto/ExerciseResponse.java | 4 +- .../api}/dto/ExerciseSubmissionPayload.java | 2 +- .../api}/dto/ExerciseSubmissionResponse.java | 4 +- .../api}/dto/GeoPointResponse.java | 4 +- .../api}/dto/GymResponse.java | 4 +- .../api}/dto/GymSimpleResponse.java | 4 +- .../{ => domains/api}/model/City.java | 2 +- .../{ => domains/api}/model/CityId.java | 2 +- .../{ => domains/api}/model/Country.java | 2 +- .../{ => domains/api}/model/GeoPoint.java | 2 +- .../{ => domains/api}/model/Gym.java | 2 +- .../{ => domains/api}/model/GymId.java | 2 +- .../api}/model/LeaderboardTimeframe.java | 2 +- .../api}/model/exercise/Exercise.java | 2 +- .../model/exercise/ExerciseSubmission.java | 4 +- .../api}/service/ExerciseService.java | 6 +- .../{ => domains/api}/service/GymService.java | 14 +-- .../api}/service/LeaderboardService.java | 18 ++-- .../api}/service/cdn_client/CdnClient.java | 2 +- .../service/cdn_client/UploadsClient.java | 2 +- .../submission/ExerciseSubmissionService.java | 20 ++-- .../auth}/controller/AuthController.java | 28 ++++-- .../auth/dao/PasswordResetCodeRepository.java | 14 +++ .../auth/dao}/RoleRepository.java | 4 +- .../dao}/UserActivationCodeRepository.java | 4 +- .../auth/dao}/UserRepository.java | 4 +- .../auth/dto/PasswordResetPayload.java | 3 + .../auth}/dto/TokenCredentials.java | 2 +- .../domains/auth/dto/TokenResponse.java | 3 + .../auth/dto/UserActivationPayload.java | 3 + .../auth}/dto/UserCreationPayload.java | 2 +- .../auth}/dto/UserResponse.java | 4 +- .../domains/auth/model/PasswordResetCode.java | 39 ++++++++ .../auth => domains/auth/model}/Role.java | 2 +- .../auth/model}/TokenAuthentication.java | 2 +- .../auth => domains/auth/model}/User.java | 6 +- .../auth/model}/UserActivationCode.java | 2 +- .../auth/service}/TokenService.java | 14 +-- .../auth/service}/UserService.java | 99 ++++++++++++++++--- .../gymboard_api/util/SampleDataLoader.java | 40 ++++---- .../gymboard_api/util/StringGenerator.java | 25 +++++ .../src/main/resources/application.properties | 5 - .../GymboardApiApplicationTests.java | 1 - .../src/test/resources/application.properties | 15 +++ 60 files changed, 363 insertions(+), 166 deletions(-) delete mode 100644 gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/TokenResponse.java delete mode 100644 gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserActivationPayload.java rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/controller/ExerciseController.java (70%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/controller/GymController.java (68%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/controller/LeaderboardController.java (83%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/controller/SubmissionController.java (75%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/dao/CityRepository.java (73%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/dao/CountryRepository.java (63%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/dao/GymRepository.java (78%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/dao/exercise/ExerciseRepository.java (60%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/dao/exercise/ExerciseSubmissionRepository.java (70%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/api}/dto/CompoundGymId.java (94%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/api}/dto/ExerciseResponse.java (60%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/api}/dto/ExerciseSubmissionPayload.java (75%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/api}/dto/ExerciseSubmissionResponse.java (85%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/api}/dto/GeoPointResponse.java (63%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/api}/dto/GymResponse.java (86%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/api}/dto/GymSimpleResponse.java (73%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/City.java (89%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/CityId.java (94%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/Country.java (90%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/GeoPoint.java (94%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/Gym.java (96%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/GymId.java (94%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/LeaderboardTimeframe.java (93%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/exercise/Exercise.java (91%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/model/exercise/ExerciseSubmission.java (94%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/service/ExerciseService.java (74%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/service/GymService.java (78%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/service/LeaderboardService.java (81%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/service/cdn_client/CdnClient.java (96%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/service/cdn_client/UploadsClient.java (89%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/api}/service/submission/ExerciseSubmissionService.java (79%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{ => domains/auth}/controller/AuthController.java (75%) create mode 100644 gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/PasswordResetCodeRepository.java rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{dao/auth => domains/auth/dao}/RoleRepository.java (63%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{dao/auth => domains/auth/dao}/UserActivationCodeRepository.java (70%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{dao/auth => domains/auth/dao}/UserRepository.java (86%) create mode 100644 gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/PasswordResetPayload.java rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/auth}/dto/TokenCredentials.java (57%) create mode 100644 gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/TokenResponse.java create mode 100644 gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserActivationPayload.java rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/auth}/dto/UserCreationPayload.java (62%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{controller => domains/auth}/dto/UserResponse.java (67%) create mode 100644 gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/PasswordResetCode.java rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{model/auth => domains/auth/model}/Role.java (87%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{model/auth => domains/auth/model}/TokenAuthentication.java (93%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{model/auth => domains/auth/model}/User.java (91%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{model/auth => domains/auth/model}/UserActivationCode.java (93%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{service/auth => domains/auth/service}/TokenService.java (89%) rename gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/{service/auth => domains/auth/service}/UserService.java (53%) create mode 100644 gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/util/StringGenerator.java create mode 100644 gymboard-api/src/test/resources/application.properties diff --git a/gymboard-api/README.md b/gymboard-api/README.md index 581dd03..02e9b06 100644 --- a/gymboard-api/README.md +++ b/gymboard-api/README.md @@ -4,8 +4,18 @@ An HTTP/REST API powered by Java and Spring Boot. This API serves as the main en ## Development +To get started, follow these steps: +1. Clone the repository, and open this project it in your editor. (Open the pom.xml file if you're using a maven-aware editor). +2. Run `./gen_keys.d` to generate the keys that will be used by this application for signing JWT tokens. (Requires a D lang installation). +3. Make sure the *gymboard-cdn* service is running locally. +4. Boot up the project. + +### Sample Data + To ease development, `nl.andrewlalis.gymboard_api.util.SampleDataLoader` will run on startup and populate the database with some sample entities. You can regenerate this data by manually deleting the database, and deleting the `.sample_data` marker file that's generated in the project directory. +You should have the *gymboard-cdn* project running when starting up this API, since the sample data includes videos that will be uploaded as part of some sample submissions. + ## ULIDs For entities that don't need a human-readable primary key (or keys), we choose to use [ULID](https://github.com/ulid/spec) strings, which are like UUIDs, but use a timestamp based preamble such that their values are monotonically increasing, and lexicographically ordered by creation time. The result is a pseudorandom string of 26 characters which appears random to a human, yet is efficient as a primary key. It's also near-impossible for automated systems to guess previous/next ids. diff --git a/gymboard-api/pom.xml b/gymboard-api/pom.xml index 39829b3..fe9f07f 100644 --- a/gymboard-api/pom.xml +++ b/gymboard-api/pom.xml @@ -77,8 +77,20 @@ org.springframework.boot spring-boot-starter-test - - compile + test + + + org.mockito + mockito-core + 5.1.1 + test + + + + com.h2database + h2 + 2.1.214 + test diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/config/SecurityConfig.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/config/SecurityConfig.java index 322b02f..a9cffbd 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/config/SecurityConfig.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/config/SecurityConfig.java @@ -46,7 +46,8 @@ public class SecurityConfig { "/exercises", "/leaderboards", "/gyms/**", - "/submissions/**" + "/submissions/**", + "/auth/reset-password" ).permitAll() .requestMatchers(// Allow the following POST endpoints to be public. HttpMethod.POST, @@ -54,7 +55,8 @@ public class SecurityConfig { "/gyms/*/submissions/upload", "/auth/token", "/auth/register", - "/auth/activate" + "/auth/activate", + "/auth/reset-password" ).permitAll() // Everything else must be authenticated, just to be safe. .anyRequest().authenticated(); diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/config/TokenAuthenticationFilter.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/config/TokenAuthenticationFilter.java index caa1615..510e6ee 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/config/TokenAuthenticationFilter.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/config/TokenAuthenticationFilter.java @@ -6,9 +6,9 @@ import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import nl.andrewlalis.gymboard_api.dao.auth.UserRepository; -import nl.andrewlalis.gymboard_api.model.auth.TokenAuthentication; -import nl.andrewlalis.gymboard_api.service.auth.TokenService; +import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository; +import nl.andrewlalis.gymboard_api.domains.auth.model.TokenAuthentication; +import nl.andrewlalis.gymboard_api.domains.auth.service.TokenService; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/TokenResponse.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/TokenResponse.java deleted file mode 100644 index 99aef46..0000000 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/TokenResponse.java +++ /dev/null @@ -1,3 +0,0 @@ -package nl.andrewlalis.gymboard_api.controller.dto; - -public record TokenResponse(String token) {} diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserActivationPayload.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserActivationPayload.java deleted file mode 100644 index 5f00816..0000000 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserActivationPayload.java +++ /dev/null @@ -1,3 +0,0 @@ -package nl.andrewlalis.gymboard_api.controller.dto; - -public record UserActivationPayload(String code) {} diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/ExerciseController.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/ExerciseController.java similarity index 70% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/ExerciseController.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/ExerciseController.java index 70ce9da..32bfc20 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/ExerciseController.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/ExerciseController.java @@ -1,7 +1,7 @@ -package nl.andrewlalis.gymboard_api.controller; +package nl.andrewlalis.gymboard_api.domains.api.controller; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseResponse; -import nl.andrewlalis.gymboard_api.service.ExerciseService; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseResponse; +import nl.andrewlalis.gymboard_api.domains.api.service.ExerciseService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/GymController.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/GymController.java similarity index 68% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/GymController.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/GymController.java index 5cf4cbd..927e86c 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/GymController.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/GymController.java @@ -1,11 +1,11 @@ -package nl.andrewlalis.gymboard_api.controller; +package nl.andrewlalis.gymboard_api.domains.api.controller; -import nl.andrewlalis.gymboard_api.controller.dto.CompoundGymId; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionPayload; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionResponse; -import nl.andrewlalis.gymboard_api.controller.dto.GymResponse; -import nl.andrewlalis.gymboard_api.service.GymService; -import nl.andrewlalis.gymboard_api.service.submission.ExerciseSubmissionService; +import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionPayload; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse; +import nl.andrewlalis.gymboard_api.domains.api.dto.GymResponse; +import nl.andrewlalis.gymboard_api.domains.api.service.GymService; +import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService; import org.springframework.web.bind.annotation.*; import java.util.List; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/LeaderboardController.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/LeaderboardController.java similarity index 83% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/LeaderboardController.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/LeaderboardController.java index 1f34eed..a9d7336 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/LeaderboardController.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/LeaderboardController.java @@ -1,7 +1,7 @@ -package nl.andrewlalis.gymboard_api.controller; +package nl.andrewlalis.gymboard_api.domains.api.controller; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionResponse; -import nl.andrewlalis.gymboard_api.service.LeaderboardService; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse; +import nl.andrewlalis.gymboard_api.domains.api.service.LeaderboardService; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.web.bind.annotation.GetMapping; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/SubmissionController.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/SubmissionController.java similarity index 75% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/SubmissionController.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/SubmissionController.java index 3721c7e..5c496e3 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/SubmissionController.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/controller/SubmissionController.java @@ -1,7 +1,7 @@ -package nl.andrewlalis.gymboard_api.controller; +package nl.andrewlalis.gymboard_api.domains.api.controller; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionResponse; -import nl.andrewlalis.gymboard_api.service.submission.ExerciseSubmissionService; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse; +import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/CityRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/CityRepository.java similarity index 73% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/CityRepository.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/CityRepository.java index 3d8661a..51b1314 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/CityRepository.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/CityRepository.java @@ -1,7 +1,7 @@ -package nl.andrewlalis.gymboard_api.dao; +package nl.andrewlalis.gymboard_api.domains.api.dao; -import nl.andrewlalis.gymboard_api.model.City; -import nl.andrewlalis.gymboard_api.model.CityId; +import nl.andrewlalis.gymboard_api.domains.api.model.City; +import nl.andrewlalis.gymboard_api.domains.api.model.CityId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/CountryRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/CountryRepository.java similarity index 63% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/CountryRepository.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/CountryRepository.java index db95810..3580e71 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/CountryRepository.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/CountryRepository.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.dao; +package nl.andrewlalis.gymboard_api.domains.api.dao; -import nl.andrewlalis.gymboard_api.model.Country; +import nl.andrewlalis.gymboard_api.domains.api.model.Country; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/GymRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/GymRepository.java similarity index 78% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/GymRepository.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/GymRepository.java index ae164c1..e31820b 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/GymRepository.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/GymRepository.java @@ -1,8 +1,8 @@ -package nl.andrewlalis.gymboard_api.dao; +package nl.andrewlalis.gymboard_api.domains.api.dao; -import nl.andrewlalis.gymboard_api.controller.dto.CompoundGymId; -import nl.andrewlalis.gymboard_api.model.Gym; -import nl.andrewlalis.gymboard_api.model.GymId; +import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId; +import nl.andrewlalis.gymboard_api.domains.api.model.Gym; +import nl.andrewlalis.gymboard_api.domains.api.model.GymId; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/exercise/ExerciseRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/exercise/ExerciseRepository.java similarity index 60% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/exercise/ExerciseRepository.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/exercise/ExerciseRepository.java index b83f779..cdf3bd7 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/exercise/ExerciseRepository.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/exercise/ExerciseRepository.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.dao.exercise; +package nl.andrewlalis.gymboard_api.domains.api.dao.exercise; -import nl.andrewlalis.gymboard_api.model.exercise.Exercise; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/exercise/ExerciseSubmissionRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/exercise/ExerciseSubmissionRepository.java similarity index 70% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/exercise/ExerciseSubmissionRepository.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/exercise/ExerciseSubmissionRepository.java index 2f02130..cd978c5 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/exercise/ExerciseSubmissionRepository.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dao/exercise/ExerciseSubmissionRepository.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.dao.exercise; +package nl.andrewlalis.gymboard_api.domains.api.dao.exercise; -import nl.andrewlalis.gymboard_api.model.exercise.ExerciseSubmission; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.stereotype.Repository; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/CompoundGymId.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/CompoundGymId.java similarity index 94% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/CompoundGymId.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/CompoundGymId.java index 6fe8ee8..7d5eb02 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/CompoundGymId.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/CompoundGymId.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.api.dto; import org.springframework.http.HttpStatus; import org.springframework.web.server.ResponseStatusException; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseResponse.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseResponse.java similarity index 60% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseResponse.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseResponse.java index 650cf29..59007d9 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseResponse.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseResponse.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.api.dto; -import nl.andrewlalis.gymboard_api.model.exercise.Exercise; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise; public record ExerciseResponse( String shortName, diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseSubmissionPayload.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseSubmissionPayload.java similarity index 75% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseSubmissionPayload.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseSubmissionPayload.java index 690e405..b7c1d95 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseSubmissionPayload.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseSubmissionPayload.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.api.dto; public record ExerciseSubmissionPayload( String name, diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseSubmissionResponse.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseSubmissionResponse.java similarity index 85% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseSubmissionResponse.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseSubmissionResponse.java index 50c0190..67854db 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/ExerciseSubmissionResponse.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/ExerciseSubmissionResponse.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.api.dto; -import nl.andrewlalis.gymboard_api.model.exercise.ExerciseSubmission; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission; import java.time.format.DateTimeFormatter; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GeoPointResponse.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GeoPointResponse.java similarity index 63% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GeoPointResponse.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GeoPointResponse.java index 0f3348c..8b1f1d2 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GeoPointResponse.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GeoPointResponse.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.api.dto; -import nl.andrewlalis.gymboard_api.model.GeoPoint; +import nl.andrewlalis.gymboard_api.domains.api.model.GeoPoint; public record GeoPointResponse( double latitude, diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GymResponse.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GymResponse.java similarity index 86% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GymResponse.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GymResponse.java index a11c25d..400fe86 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GymResponse.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GymResponse.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.api.dto; -import nl.andrewlalis.gymboard_api.model.Gym; +import nl.andrewlalis.gymboard_api.domains.api.model.Gym; import java.time.format.DateTimeFormatter; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GymSimpleResponse.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GymSimpleResponse.java similarity index 73% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GymSimpleResponse.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GymSimpleResponse.java index 713a800..0c8b140 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/GymSimpleResponse.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/dto/GymSimpleResponse.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.api.dto; -import nl.andrewlalis.gymboard_api.model.Gym; +import nl.andrewlalis.gymboard_api.domains.api.model.Gym; public record GymSimpleResponse( String countryCode, diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/City.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/City.java similarity index 89% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/City.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/City.java index 91c9837..c4f32ad 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/City.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/City.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model; +package nl.andrewlalis.gymboard_api.domains.api.model; import jakarta.persistence.*; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/CityId.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/CityId.java similarity index 94% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/CityId.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/CityId.java index 699988e..0f3f090 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/CityId.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/CityId.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model; +package nl.andrewlalis.gymboard_api.domains.api.model; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Country.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/Country.java similarity index 90% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Country.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/Country.java index cdee1f3..b624362 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Country.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/Country.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model; +package nl.andrewlalis.gymboard_api.domains.api.model; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GeoPoint.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/GeoPoint.java similarity index 94% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GeoPoint.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/GeoPoint.java index c82d30b..12740ed 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GeoPoint.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/GeoPoint.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model; +package nl.andrewlalis.gymboard_api.domains.api.model; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Gym.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/Gym.java similarity index 96% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Gym.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/Gym.java index 3ea835f..c04d2b8 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/Gym.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/Gym.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model; +package nl.andrewlalis.gymboard_api.domains.api.model; import jakarta.persistence.*; import org.hibernate.annotations.CreationTimestamp; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GymId.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/GymId.java similarity index 94% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GymId.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/GymId.java index 09e4f21..f2c4417 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/GymId.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/GymId.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model; +package nl.andrewlalis.gymboard_api.domains.api.model; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/LeaderboardTimeframe.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/LeaderboardTimeframe.java similarity index 93% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/LeaderboardTimeframe.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/LeaderboardTimeframe.java index 7e5b9c0..349fdde 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/LeaderboardTimeframe.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/LeaderboardTimeframe.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model; +package nl.andrewlalis.gymboard_api.domains.api.model; import java.time.Duration; import java.time.LocalDateTime; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/exercise/Exercise.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/exercise/Exercise.java similarity index 91% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/exercise/Exercise.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/exercise/Exercise.java index 1415570..baaf698 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/exercise/Exercise.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/exercise/Exercise.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model.exercise; +package nl.andrewlalis.gymboard_api.domains.api.model.exercise; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/exercise/ExerciseSubmission.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/exercise/ExerciseSubmission.java similarity index 94% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/exercise/ExerciseSubmission.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/exercise/ExerciseSubmission.java index d767918..fd81c8f 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/exercise/ExerciseSubmission.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/model/exercise/ExerciseSubmission.java @@ -1,7 +1,7 @@ -package nl.andrewlalis.gymboard_api.model.exercise; +package nl.andrewlalis.gymboard_api.domains.api.model.exercise; import jakarta.persistence.*; -import nl.andrewlalis.gymboard_api.model.Gym; +import nl.andrewlalis.gymboard_api.domains.api.model.Gym; import org.hibernate.annotations.CreationTimestamp; import java.math.BigDecimal; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/ExerciseService.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/ExerciseService.java similarity index 74% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/ExerciseService.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/ExerciseService.java index 4c201cb..9312228 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/ExerciseService.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/ExerciseService.java @@ -1,7 +1,7 @@ -package nl.andrewlalis.gymboard_api.service; +package nl.andrewlalis.gymboard_api.domains.api.service; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseResponse; -import nl.andrewlalis.gymboard_api.dao.exercise.ExerciseRepository; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseResponse; +import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseRepository; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/GymService.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/GymService.java similarity index 78% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/GymService.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/GymService.java index 04f54b2..2739408 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/GymService.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/GymService.java @@ -1,11 +1,11 @@ -package nl.andrewlalis.gymboard_api.service; +package nl.andrewlalis.gymboard_api.domains.api.service; -import nl.andrewlalis.gymboard_api.controller.dto.CompoundGymId; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionResponse; -import nl.andrewlalis.gymboard_api.controller.dto.GymResponse; -import nl.andrewlalis.gymboard_api.dao.GymRepository; -import nl.andrewlalis.gymboard_api.dao.exercise.ExerciseSubmissionRepository; -import nl.andrewlalis.gymboard_api.model.Gym; +import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse; +import nl.andrewlalis.gymboard_api.domains.api.dto.GymResponse; +import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository; +import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseSubmissionRepository; +import nl.andrewlalis.gymboard_api.domains.api.model.Gym; import nl.andrewlalis.gymboard_api.util.PredicateBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/LeaderboardService.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/LeaderboardService.java similarity index 81% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/LeaderboardService.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/LeaderboardService.java index 09b193d..db3cb0b 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/LeaderboardService.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/LeaderboardService.java @@ -1,13 +1,13 @@ -package nl.andrewlalis.gymboard_api.service; +package nl.andrewlalis.gymboard_api.domains.api.service; -import nl.andrewlalis.gymboard_api.controller.dto.CompoundGymId; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionResponse; -import nl.andrewlalis.gymboard_api.dao.GymRepository; -import nl.andrewlalis.gymboard_api.dao.exercise.ExerciseRepository; -import nl.andrewlalis.gymboard_api.dao.exercise.ExerciseSubmissionRepository; -import nl.andrewlalis.gymboard_api.model.Gym; -import nl.andrewlalis.gymboard_api.model.LeaderboardTimeframe; -import nl.andrewlalis.gymboard_api.model.exercise.Exercise; +import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse; +import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository; +import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseRepository; +import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseSubmissionRepository; +import nl.andrewlalis.gymboard_api.domains.api.model.Gym; +import nl.andrewlalis.gymboard_api.domains.api.model.LeaderboardTimeframe; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise; import nl.andrewlalis.gymboard_api.util.PredicateBuilder; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/cdn_client/CdnClient.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/cdn_client/CdnClient.java similarity index 96% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/cdn_client/CdnClient.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/cdn_client/CdnClient.java index d328eae..8029b94 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/cdn_client/CdnClient.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/cdn_client/CdnClient.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.service.cdn_client; +package nl.andrewlalis.gymboard_api.domains.api.service.cdn_client; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/cdn_client/UploadsClient.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/cdn_client/UploadsClient.java similarity index 89% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/cdn_client/UploadsClient.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/cdn_client/UploadsClient.java index 1bebc65..fc8a954 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/cdn_client/UploadsClient.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/cdn_client/UploadsClient.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.service.cdn_client; +package nl.andrewlalis.gymboard_api.domains.api.service.cdn_client; import java.nio.file.Path; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/submission/ExerciseSubmissionService.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/submission/ExerciseSubmissionService.java similarity index 79% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/submission/ExerciseSubmissionService.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/submission/ExerciseSubmissionService.java index 96ff7b5..75c7b12 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/submission/ExerciseSubmissionService.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/api/service/submission/ExerciseSubmissionService.java @@ -1,14 +1,14 @@ -package nl.andrewlalis.gymboard_api.service.submission; +package nl.andrewlalis.gymboard_api.domains.api.service.submission; -import nl.andrewlalis.gymboard_api.controller.dto.CompoundGymId; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionPayload; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionResponse; -import nl.andrewlalis.gymboard_api.dao.GymRepository; -import nl.andrewlalis.gymboard_api.dao.exercise.ExerciseRepository; -import nl.andrewlalis.gymboard_api.dao.exercise.ExerciseSubmissionRepository; -import nl.andrewlalis.gymboard_api.model.Gym; -import nl.andrewlalis.gymboard_api.model.exercise.Exercise; -import nl.andrewlalis.gymboard_api.model.exercise.ExerciseSubmission; +import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionPayload; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionResponse; +import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository; +import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseRepository; +import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseSubmissionRepository; +import nl.andrewlalis.gymboard_api.domains.api.model.Gym; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission; import nl.andrewlalis.gymboard_api.util.ULID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/AuthController.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/controller/AuthController.java similarity index 75% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/AuthController.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/controller/AuthController.java index 6ecc175..883841e 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/AuthController.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/controller/AuthController.java @@ -1,15 +1,13 @@ -package nl.andrewlalis.gymboard_api.controller; +package nl.andrewlalis.gymboard_api.domains.auth.controller; -import nl.andrewlalis.gymboard_api.controller.dto.*; -import nl.andrewlalis.gymboard_api.model.auth.User; -import nl.andrewlalis.gymboard_api.service.auth.TokenService; -import nl.andrewlalis.gymboard_api.service.auth.UserService; +import nl.andrewlalis.gymboard_api.domains.auth.dto.*; +import nl.andrewlalis.gymboard_api.domains.auth.model.User; +import nl.andrewlalis.gymboard_api.domains.auth.service.TokenService; +import nl.andrewlalis.gymboard_api.domains.auth.service.UserService; +import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController public class AuthController { @@ -80,4 +78,16 @@ public class AuthController { public UserResponse getMyUser(@AuthenticationPrincipal User user) { return new UserResponse(user); } + + @GetMapping(path = "/auth/reset-password") + public ResponseEntity generatePasswordResetCode(@RequestParam String email) { + userService.generatePasswordResetCode(email); + return ResponseEntity.ok().build(); + } + + @PostMapping(path = "/auth/reset-password") + public ResponseEntity resetPassword(@RequestBody PasswordResetPayload payload) { + userService.resetUserPassword(payload); + return ResponseEntity.ok().build(); + } } diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/PasswordResetCodeRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/PasswordResetCodeRepository.java new file mode 100644 index 0000000..6efd5d8 --- /dev/null +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/PasswordResetCodeRepository.java @@ -0,0 +1,14 @@ +package nl.andrewlalis.gymboard_api.domains.auth.dao; + +import nl.andrewlalis.gymboard_api.domains.auth.model.PasswordResetCode; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.stereotype.Repository; + +import java.time.LocalDateTime; + +@Repository +public interface PasswordResetCodeRepository extends JpaRepository { + @Modifying + void deleteAllByCreatedAtBefore(LocalDateTime cutoff); +} diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/RoleRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/RoleRepository.java similarity index 63% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/RoleRepository.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/RoleRepository.java index 50a2b5d..0101fb6 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/RoleRepository.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/RoleRepository.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.dao.auth; +package nl.andrewlalis.gymboard_api.domains.auth.dao; -import nl.andrewlalis.gymboard_api.model.auth.Role; +import nl.andrewlalis.gymboard_api.domains.auth.model.Role; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/UserActivationCodeRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/UserActivationCodeRepository.java similarity index 70% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/UserActivationCodeRepository.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/UserActivationCodeRepository.java index d1191aa..4488d40 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/UserActivationCodeRepository.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/UserActivationCodeRepository.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.dao.auth; +package nl.andrewlalis.gymboard_api.domains.auth.dao; -import nl.andrewlalis.gymboard_api.model.auth.UserActivationCode; +import nl.andrewlalis.gymboard_api.domains.auth.model.UserActivationCode; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/UserRepository.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/UserRepository.java similarity index 86% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/UserRepository.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/UserRepository.java index 31e7d58..030ab2e 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/dao/auth/UserRepository.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dao/UserRepository.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.dao.auth; +package nl.andrewlalis.gymboard_api.domains.auth.dao; -import nl.andrewlalis.gymboard_api.model.auth.User; +import nl.andrewlalis.gymboard_api.domains.auth.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/PasswordResetPayload.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/PasswordResetPayload.java new file mode 100644 index 0000000..d8e264e --- /dev/null +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/PasswordResetPayload.java @@ -0,0 +1,3 @@ +package nl.andrewlalis.gymboard_api.domains.auth.dto; + +public record PasswordResetPayload(String code, String newPassword) {} diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/TokenCredentials.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/TokenCredentials.java similarity index 57% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/TokenCredentials.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/TokenCredentials.java index 5637abb..6745871 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/TokenCredentials.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/TokenCredentials.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.auth.dto; public record TokenCredentials( String email, diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/TokenResponse.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/TokenResponse.java new file mode 100644 index 0000000..53f7d81 --- /dev/null +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/TokenResponse.java @@ -0,0 +1,3 @@ +package nl.andrewlalis.gymboard_api.domains.auth.dto; + +public record TokenResponse(String token) {} diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserActivationPayload.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserActivationPayload.java new file mode 100644 index 0000000..1a9d6a7 --- /dev/null +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserActivationPayload.java @@ -0,0 +1,3 @@ +package nl.andrewlalis.gymboard_api.domains.auth.dto; + +public record UserActivationPayload(String code) {} diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserCreationPayload.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserCreationPayload.java similarity index 62% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserCreationPayload.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserCreationPayload.java index 4e8446f..6c18539 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserCreationPayload.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserCreationPayload.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.auth.dto; public record UserCreationPayload( String email, diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserResponse.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserResponse.java similarity index 67% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserResponse.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserResponse.java index 592ddd9..6995fef 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/controller/dto/UserResponse.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/dto/UserResponse.java @@ -1,6 +1,6 @@ -package nl.andrewlalis.gymboard_api.controller.dto; +package nl.andrewlalis.gymboard_api.domains.auth.dto; -import nl.andrewlalis.gymboard_api.model.auth.User; +import nl.andrewlalis.gymboard_api.domains.auth.model.User; public record UserResponse( String id, diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/PasswordResetCode.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/PasswordResetCode.java new file mode 100644 index 0000000..81867c8 --- /dev/null +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/PasswordResetCode.java @@ -0,0 +1,39 @@ +package nl.andrewlalis.gymboard_api.domains.auth.model; + +import jakarta.persistence.*; +import org.hibernate.annotations.CreationTimestamp; + +import java.time.LocalDateTime; + +@Entity +@Table(name = "auth_user_password_reset_code") +public class PasswordResetCode { + @Id + @Column(nullable = false, updatable = false, length = 127) + private String code; + + @CreationTimestamp + private LocalDateTime createdAt; + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + private User user; + + public PasswordResetCode() {} + + public PasswordResetCode(String code, User user) { + this.code = code; + this.user = user; + } + + public String getCode() { + return code; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public User getUser() { + return user; + } +} diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/Role.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/Role.java similarity index 87% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/Role.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/Role.java index 4c9dea8..318c9cc 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/Role.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/Role.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model.auth; +package nl.andrewlalis.gymboard_api.domains.auth.model; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/TokenAuthentication.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/TokenAuthentication.java similarity index 93% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/TokenAuthentication.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/TokenAuthentication.java index 8860369..45d8933 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/TokenAuthentication.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/TokenAuthentication.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model.auth; +package nl.andrewlalis.gymboard_api.domains.auth.model; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/User.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/User.java similarity index 91% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/User.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/User.java index 3acc45d..8d5c801 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/User.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/User.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model.auth; +package nl.andrewlalis.gymboard_api.domains.auth.model; import jakarta.persistence.*; import org.hibernate.annotations.CreationTimestamp; @@ -72,6 +72,10 @@ public class User { return passwordHash; } + public void setPasswordHash(String passwordHash) { + this.passwordHash = passwordHash; + } + public String getName() { return name; } diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/UserActivationCode.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/UserActivationCode.java similarity index 93% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/UserActivationCode.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/UserActivationCode.java index f1d8fd9..c3c3a24 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/model/auth/UserActivationCode.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/model/UserActivationCode.java @@ -1,4 +1,4 @@ -package nl.andrewlalis.gymboard_api.model.auth; +package nl.andrewlalis.gymboard_api.domains.auth.model; import jakarta.persistence.*; import org.hibernate.annotations.CreationTimestamp; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/auth/TokenService.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/service/TokenService.java similarity index 89% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/auth/TokenService.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/service/TokenService.java index 6556d2b..28cc61b 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/auth/TokenService.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/service/TokenService.java @@ -1,15 +1,15 @@ -package nl.andrewlalis.gymboard_api.service.auth; +package nl.andrewlalis.gymboard_api.domains.auth.service; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import jakarta.servlet.http.HttpServletRequest; -import nl.andrewlalis.gymboard_api.controller.dto.TokenCredentials; -import nl.andrewlalis.gymboard_api.controller.dto.TokenResponse; -import nl.andrewlalis.gymboard_api.dao.auth.UserRepository; -import nl.andrewlalis.gymboard_api.model.auth.Role; -import nl.andrewlalis.gymboard_api.model.auth.TokenAuthentication; -import nl.andrewlalis.gymboard_api.model.auth.User; +import nl.andrewlalis.gymboard_api.domains.auth.dto.TokenCredentials; +import nl.andrewlalis.gymboard_api.domains.auth.dto.TokenResponse; +import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository; +import nl.andrewlalis.gymboard_api.domains.auth.model.Role; +import nl.andrewlalis.gymboard_api.domains.auth.model.TokenAuthentication; +import nl.andrewlalis.gymboard_api.domains.auth.model.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/auth/UserService.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/service/UserService.java similarity index 53% rename from gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/auth/UserService.java rename to gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/service/UserService.java index 578d78e..cfc979c 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/service/auth/UserService.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/domains/auth/service/UserService.java @@ -1,14 +1,18 @@ -package nl.andrewlalis.gymboard_api.service.auth; +package nl.andrewlalis.gymboard_api.domains.auth.service; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; -import nl.andrewlalis.gymboard_api.controller.dto.UserActivationPayload; -import nl.andrewlalis.gymboard_api.controller.dto.UserCreationPayload; -import nl.andrewlalis.gymboard_api.controller.dto.UserResponse; -import nl.andrewlalis.gymboard_api.dao.auth.UserActivationCodeRepository; -import nl.andrewlalis.gymboard_api.dao.auth.UserRepository; -import nl.andrewlalis.gymboard_api.model.auth.User; -import nl.andrewlalis.gymboard_api.model.auth.UserActivationCode; +import nl.andrewlalis.gymboard_api.domains.auth.dao.PasswordResetCodeRepository; +import nl.andrewlalis.gymboard_api.domains.auth.dto.PasswordResetPayload; +import nl.andrewlalis.gymboard_api.domains.auth.dto.UserActivationPayload; +import nl.andrewlalis.gymboard_api.domains.auth.dto.UserCreationPayload; +import nl.andrewlalis.gymboard_api.domains.auth.dto.UserResponse; +import nl.andrewlalis.gymboard_api.domains.auth.dao.UserActivationCodeRepository; +import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository; +import nl.andrewlalis.gymboard_api.domains.auth.model.PasswordResetCode; +import nl.andrewlalis.gymboard_api.domains.auth.model.User; +import nl.andrewlalis.gymboard_api.domains.auth.model.UserActivationCode; +import nl.andrewlalis.gymboard_api.util.StringGenerator; import nl.andrewlalis.gymboard_api.util.ULID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,6 +35,7 @@ public class UserService { private final UserRepository userRepository; private final UserActivationCodeRepository activationCodeRepository; + private final PasswordResetCodeRepository passwordResetCodeRepository; private final ULID ulid; private final PasswordEncoder passwordEncoder; private final JavaMailSender mailSender; @@ -40,12 +45,15 @@ public class UserService { public UserService( UserRepository userRepository, - UserActivationCodeRepository activationCodeRepository, ULID ulid, + UserActivationCodeRepository activationCodeRepository, + PasswordResetCodeRepository passwordResetCodeRepository, + ULID ulid, PasswordEncoder passwordEncoder, JavaMailSender mailSender ) { this.userRepository = userRepository; this.activationCodeRepository = activationCodeRepository; + this.passwordResetCodeRepository = passwordResetCodeRepository; this.ulid = ulid; this.passwordEncoder = passwordEncoder; this.mailSender = mailSender; @@ -117,13 +125,74 @@ public class UserService { public UserResponse activateUser(UserActivationPayload payload) { UserActivationCode activationCode = activationCodeRepository.findByCode(payload.code()) .orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST)); - LocalDateTime cutoff = LocalDateTime.now().minusDays(1); - if (activationCode.getCreatedAt().isBefore(cutoff)) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Code is expired."); - } User user = activationCode.getUser(); - user.setActivated(true); - userRepository.save(user); + if (!user.isActivated()) { + LocalDateTime cutoff = LocalDateTime.now().minusDays(1); + if (activationCode.getCreatedAt().isBefore(cutoff)) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Code is expired."); + } + user.setActivated(true); + userRepository.save(user); + } + activationCodeRepository.delete(activationCode); return new UserResponse(user); } + + @Transactional + public void generatePasswordResetCode(String email) { + User user = userRepository.findByEmail(email) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + if (!user.isActivated()) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + + PasswordResetCode passwordResetCode = passwordResetCodeRepository.save(new PasswordResetCode( + StringGenerator.randomString(127, StringGenerator.Alphabet.ALPHANUMERIC), + user + )); + + // Send email. + String resetLink = webOrigin + "/password-reset?code=" + passwordResetCode.getCode(); + String emailContent = String.format( + """ +

Hello %s,

+ +

+ You've just requested to reset your password. +

+

+ Please click here to reset your password. +

+ """, + user.getName(), + resetLink + ); + MimeMessage msg = mailSender.createMimeMessage(); + try { + MimeMessageHelper helper = new MimeMessageHelper(msg, "UTF-8"); + helper.setFrom("Gymboard "); + helper.setSubject("Gymboard Account Password Reset"); + helper.setTo(user.getEmail()); + helper.setText(emailContent, true); + mailSender.send(msg); + } catch (MessagingException e) { + log.error("Error sending user password reset email.", e); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @Transactional + public void resetUserPassword(PasswordResetPayload payload) { + PasswordResetCode code = passwordResetCodeRepository.findById(payload.code()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + LocalDateTime cutoff = LocalDateTime.now().minusMinutes(30); + if (code.getCreatedAt().isBefore(cutoff)) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + + // TODO: Validate password. + + code.getUser().setPasswordHash(passwordEncoder.encode(payload.newPassword())); + passwordResetCodeRepository.delete(code); + } } diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/util/SampleDataLoader.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/util/SampleDataLoader.java index 3a3d491..b72af85 100644 --- a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/util/SampleDataLoader.java +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/util/SampleDataLoader.java @@ -1,25 +1,25 @@ package nl.andrewlalis.gymboard_api.util; -import nl.andrewlalis.gymboard_api.controller.dto.CompoundGymId; -import nl.andrewlalis.gymboard_api.controller.dto.ExerciseSubmissionPayload; -import nl.andrewlalis.gymboard_api.controller.dto.UserCreationPayload; -import nl.andrewlalis.gymboard_api.dao.CityRepository; -import nl.andrewlalis.gymboard_api.dao.CountryRepository; -import nl.andrewlalis.gymboard_api.dao.GymRepository; -import nl.andrewlalis.gymboard_api.dao.auth.RoleRepository; -import nl.andrewlalis.gymboard_api.dao.auth.UserRepository; -import nl.andrewlalis.gymboard_api.dao.exercise.ExerciseRepository; -import nl.andrewlalis.gymboard_api.model.City; -import nl.andrewlalis.gymboard_api.model.Country; -import nl.andrewlalis.gymboard_api.model.GeoPoint; -import nl.andrewlalis.gymboard_api.model.Gym; -import nl.andrewlalis.gymboard_api.model.auth.Role; -import nl.andrewlalis.gymboard_api.model.auth.User; -import nl.andrewlalis.gymboard_api.model.exercise.Exercise; -import nl.andrewlalis.gymboard_api.model.exercise.ExerciseSubmission; -import nl.andrewlalis.gymboard_api.service.auth.UserService; -import nl.andrewlalis.gymboard_api.service.cdn_client.CdnClient; -import nl.andrewlalis.gymboard_api.service.submission.ExerciseSubmissionService; +import nl.andrewlalis.gymboard_api.domains.api.dto.CompoundGymId; +import nl.andrewlalis.gymboard_api.domains.api.dto.ExerciseSubmissionPayload; +import nl.andrewlalis.gymboard_api.domains.auth.dto.UserCreationPayload; +import nl.andrewlalis.gymboard_api.domains.api.dao.CityRepository; +import nl.andrewlalis.gymboard_api.domains.api.dao.CountryRepository; +import nl.andrewlalis.gymboard_api.domains.api.dao.GymRepository; +import nl.andrewlalis.gymboard_api.domains.auth.dao.RoleRepository; +import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository; +import nl.andrewlalis.gymboard_api.domains.api.dao.exercise.ExerciseRepository; +import nl.andrewlalis.gymboard_api.domains.api.model.City; +import nl.andrewlalis.gymboard_api.domains.api.model.Country; +import nl.andrewlalis.gymboard_api.domains.api.model.GeoPoint; +import nl.andrewlalis.gymboard_api.domains.api.model.Gym; +import nl.andrewlalis.gymboard_api.domains.auth.model.Role; +import nl.andrewlalis.gymboard_api.domains.auth.model.User; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.Exercise; +import nl.andrewlalis.gymboard_api.domains.api.model.exercise.ExerciseSubmission; +import nl.andrewlalis.gymboard_api.domains.auth.service.UserService; +import nl.andrewlalis.gymboard_api.domains.api.service.cdn_client.CdnClient; +import nl.andrewlalis.gymboard_api.domains.api.service.submission.ExerciseSubmissionService; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVRecord; import org.slf4j.Logger; diff --git a/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/util/StringGenerator.java b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/util/StringGenerator.java new file mode 100644 index 0000000..7c98f3d --- /dev/null +++ b/gymboard-api/src/main/java/nl/andrewlalis/gymboard_api/util/StringGenerator.java @@ -0,0 +1,25 @@ +package nl.andrewlalis.gymboard_api.util; + +import java.security.SecureRandom; +import java.util.Random; + +public class StringGenerator { + public enum Alphabet { + ALPHANUMERIC("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); + + public final String value; + + Alphabet(String value) { + this.value = value; + } + } + + public static String randomString(int length, Alphabet alphabet) { + Random random = new SecureRandom(); + StringBuilder sb = new StringBuilder(length); + for (int i = 0; i < length; i++) { + sb.append(alphabet.value.charAt(random.nextInt(alphabet.value.length()))); + } + return sb.toString(); + } +} diff --git a/gymboard-api/src/main/resources/application.properties b/gymboard-api/src/main/resources/application.properties index 45044f6..91d36ec 100644 --- a/gymboard-api/src/main/resources/application.properties +++ b/gymboard-api/src/main/resources/application.properties @@ -1,6 +1 @@ spring.jpa.open-in-view=false - -# TODO: Find a better way than dumping files into memory. -spring.servlet.multipart.enabled=true -spring.servlet.multipart.max-file-size=1GB -spring.servlet.multipart.max-request-size=2GB diff --git a/gymboard-api/src/test/java/nl/andrewlalis/gymboard_api/GymboardApiApplicationTests.java b/gymboard-api/src/test/java/nl/andrewlalis/gymboard_api/GymboardApiApplicationTests.java index 2eeb999..399189e 100644 --- a/gymboard-api/src/test/java/nl/andrewlalis/gymboard_api/GymboardApiApplicationTests.java +++ b/gymboard-api/src/test/java/nl/andrewlalis/gymboard_api/GymboardApiApplicationTests.java @@ -5,7 +5,6 @@ import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class GymboardApiApplicationTests { - @Test void contextLoads() { } diff --git a/gymboard-api/src/test/resources/application.properties b/gymboard-api/src/test/resources/application.properties new file mode 100644 index 0000000..e997bbc --- /dev/null +++ b/gymboard-api/src/test/resources/application.properties @@ -0,0 +1,15 @@ +spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +spring.datasource.driver-class-name=org.h2.Driver + +spring.jpa.open-in-view=false + +spring.jpa.hibernate.ddl-auto=update + +spring.mail.host=127.0.0.1 +spring.mail.port=1025 +spring.mail.protocol=smtp +spring.mail.properties.mail.smtp.timeout=10000 + +app.auth.private-key-location=./private_key.der +app.web-origin=http://localhost:9000 +app.cdn-origin=http://localhost:8082