From 13f7f59989eba243760068085094a2f9538c06bc Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 31 Aug 2024 14:26:39 +0200
Subject: [PATCH 01/23] chore: add tag based event
---
.github/workflows/tag-based-thing.yaml | 38 ++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 .github/workflows/tag-based-thing.yaml
diff --git a/.github/workflows/tag-based-thing.yaml b/.github/workflows/tag-based-thing.yaml
new file mode 100644
index 00000000..57bfb274
--- /dev/null
+++ b/.github/workflows/tag-based-thing.yaml
@@ -0,0 +1,38 @@
+# Setup an action to run the frontend CI for PRs
+
+# name of the action
+name: Frontend CI
+
+# when should it run
+on:
+ push:
+ tags:
+ - v**
+
+# what should it do
+jobs:
+ # name of the job
+ build:
+ # what should it run on
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ pull-requests: write
+ # default values for all the steps
+ defaults:
+ run:
+ working-directory: frontend
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ - name: Install dependencies
+ run: npm install
+ - name: Run build
+ run: npm run build
+ - name: Run tests
+ run: npm test
+ - name: Run formatter + linter
+ run: npm run check
From e3eae98f8aa258a0c99ab76713c246ad04ffe65e Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Wed, 4 Sep 2024 20:33:36 +0200
Subject: [PATCH 02/23] chore: makes the app cacheable with Redis
---
backend/pom.xml | 4 ++++
.../com/greenfoxacademy/backend/BackendApplication.java | 2 ++
backend/src/main/resources/application.properties | 7 ++++++-
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/backend/pom.xml b/backend/pom.xml
index 455b02c5..ba7641b8 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -108,6 +108,10 @@
spring-boot-starter-mail
3.3.2
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java b/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java
index d4092c00..4eea1d00 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/BackendApplication.java
@@ -2,11 +2,13 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cache.annotation.EnableCaching;
/**
* This is the main class of the application.
*/
@SpringBootApplication
+@EnableCaching
public class BackendApplication {
public static void main(String[] args) {
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 4bdc3553..cba1486c 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -25,4 +25,9 @@ spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
# Where the verification link will redirect
-email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
\ No newline at end of file
+email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
+
+# Redis configuration
+spring.data.redis.host=localhost
+spring.data.redis.port=6379
+spring.cache.type=redis
From eeeded76d70eefc33f5ee5023918c0e276b48ccd Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Wed, 4 Sep 2024 20:51:00 +0200
Subject: [PATCH 03/23] feat: makes login and load user cacheable
---
.../backend/services/user/UserServiceImpl.java | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
index 9a1c5602..eb2634d5 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
@@ -13,8 +13,11 @@
import com.greenfoxacademy.backend.services.auth.AuthService;
import com.greenfoxacademy.backend.services.mail.EmailService;
import jakarta.transaction.Transactional;
+
import java.util.UUID;
+
import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
@@ -47,9 +50,9 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto)
try {
User saved = userRepository.save(user);
emailService.sendRegistrationEmail(
- saved.getEmail(),
- saved.getFirstName(),
- saved.getVerificationId()
+ saved.getEmail(),
+ saved.getFirstName(),
+ saved.getVerificationId()
);
return new RegisterResponseDto(saved.getId());
} catch (Exception e) {
@@ -57,7 +60,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto)
}
}
-
+ @Cacheable
@Override
public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception {
User user = userRepository.findByEmail(loginRequestDto.email())
@@ -79,7 +82,7 @@ public ProfileUpdateResponseDto profileUpdate(
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
if (
userRepository.existsByEmail(profileUpdateRequestDto.email())
- && !email.equals(profileUpdateRequestDto.email())
+ && !email.equals(profileUpdateRequestDto.email())
) {
throw new CannotUpdateUserException("Email is already taken!");
}
@@ -92,6 +95,7 @@ public ProfileUpdateResponseDto profileUpdate(
return new ProfileUpdateResponseDto(authService.generateToken(updatedUser));
}
+ @Cacheable
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository.findByEmail(username)
From b280481d552577bfb7b3f18a0218f55a0db8f4ab Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Wed, 4 Sep 2024 21:47:02 +0200
Subject: [PATCH 04/23] feat: updating and deleting the profile clears the
cache
---
.../greenfoxacademy/backend/services/user/UserServiceImpl.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
index eb2634d5..3350af4a 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
@@ -17,6 +17,7 @@
import java.util.UUID;
import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@@ -73,6 +74,7 @@ public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception
return new LoginResponseDto(authService.generateToken(user));
}
+ @CacheEvict
@Override
public ProfileUpdateResponseDto profileUpdate(
String email,
@@ -105,6 +107,7 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx
/**
* Delete the user by username.
*/
+ @CacheEvict
@Transactional
@Override
public void deleteProfile(String username) {
From b69c840048cd359ca1e3bce1c33faeec926e4fb0 Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Thu, 5 Sep 2024 20:29:30 +0200
Subject: [PATCH 05/23] chore: configure TTL with Redis
---
.../backend/config/RedisConfig.java | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java b/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
new file mode 100644
index 00000000..6ad316ac
--- /dev/null
+++ b/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
@@ -0,0 +1,33 @@
+package com.greenfoxacademy.backend.config;
+
+import org.springframework.cache.CacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.time.Duration;
+
+/**
+ * RedisConfig is a configuration class that defines the cache management strategy
+ * for Redis in the Spring Boot application. It configures the Redis Cache Manager
+ * and sets key serialization and expiration policies.
+ */
+
+@Configuration
+public class RedisConfig {
+
+ @Bean
+ public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
+ RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
+ .entryTtl(Duration.ofMinutes(5)) // Set TTL to 5 minutes
+ .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
+
+ return RedisCacheManager.builder(redisConnectionFactory)
+ .cacheDefaults(cacheConfig)
+ .build();
+ }
+}
\ No newline at end of file
From 74df238d4fed64d204ba088bdaaab8f8c0f7600b Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Thu, 5 Sep 2024 21:47:11 +0200
Subject: [PATCH 06/23] chore: configure Redis container
---
.../com/greenfoxacademy/backend/config/RedisConfig.java | 3 ++-
backend/src/main/resources/application.properties | 4 ++--
docker-compose.yaml | 8 ++++++++
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java b/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
index 6ad316ac..a7d5fd6a 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
@@ -23,7 +23,8 @@ public class RedisConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
- .entryTtl(Duration.ofMinutes(5)) // Set TTL to 5 minutes
+ .entryTtl(Duration.ofMinutes(5)) // Set TTL to 5 minutes
+ .disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
return RedisCacheManager.builder(redisConnectionFactory)
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index cba1486c..8482850c 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -28,6 +28,6 @@ spring.mail.properties.mail.smtp.starttls.enable=true
email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
# Redis configuration
-spring.data.redis.host=localhost
-spring.data.redis.port=6379
+spring.data.redis.host=${CACHE_URL:localhost}
+spring.data.redis.port=${CACHE_PORT:6379}
spring.cache.type=redis
diff --git a/docker-compose.yaml b/docker-compose.yaml
index c29112e5..ae76a93b 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -10,6 +10,11 @@ services:
POSTGRES_PASSWORD: petclinic_db_password
POSTGRES_DB: petclinic_db
+ redis-cache:
+ image: redis
+ ports:
+ - 6379:6379
+
frontend:
build:
context: ./frontend
@@ -28,5 +33,8 @@ services:
- DATABASE_USER=petclinic_db_user
- DATABASE_PASSWORD=petclinic_db_password
- CORS_URLS=http://localhost:5173
+ - CACHE_PORT=6379
+ - CACHE_URL=redis://redis-cache
depends_on:
- postgres-db
+ - redis-cache
From a81140995316ed7765116490bef353d5c9dfab98 Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Thu, 5 Sep 2024 22:11:13 +0200
Subject: [PATCH 07/23] chore: adds key - value pair to the login cache
---
.../java/com/greenfoxacademy/backend/config/RedisConfig.java | 2 +-
.../com/greenfoxacademy/backend/dtos/LoginResponseDto.java | 5 ++++-
.../backend/services/user/UserServiceImpl.java | 2 +-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java b/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
index a7d5fd6a..899e6f40 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
@@ -23,7 +23,7 @@ public class RedisConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
- .entryTtl(Duration.ofMinutes(5)) // Set TTL to 5 minutes
+ .entryTtl(Duration.ofMinutes(3)) // Set TTL to 5 minutes
.disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/LoginResponseDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/LoginResponseDto.java
index fef2c72e..7b2207bf 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/LoginResponseDto.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/LoginResponseDto.java
@@ -1,12 +1,15 @@
package com.greenfoxacademy.backend.dtos;
+import java.io.Serializable;
+
/**
* This class is responsible for the response of the login endpoint.
*
* @param token the token that is returned to identify the user
*/
+
public record LoginResponseDto(
String token
-) {
+) implements Serializable {
}
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
index 3350af4a..066472b8 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
@@ -61,7 +61,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto)
}
}
- @Cacheable
+ @Cacheable (value = "login-cache", key = "#loginRequestDto.email()")
@Override
public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception {
User user = userRepository.findByEmail(loginRequestDto.email())
From 44164818a59204d917cff6af13a39e6b59e82540 Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Thu, 5 Sep 2024 22:14:27 +0200
Subject: [PATCH 08/23] fix: eliminates cache for login due to security reasons
---
.../com/greenfoxacademy/backend/dtos/LoginResponseDto.java | 4 +---
.../backend/services/user/UserServiceImpl.java | 3 +--
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/dtos/LoginResponseDto.java b/backend/src/main/java/com/greenfoxacademy/backend/dtos/LoginResponseDto.java
index 7b2207bf..2186f2c9 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/dtos/LoginResponseDto.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/dtos/LoginResponseDto.java
@@ -1,8 +1,6 @@
package com.greenfoxacademy.backend.dtos;
-import java.io.Serializable;
-
/**
* This class is responsible for the response of the login endpoint.
*
@@ -11,5 +9,5 @@
public record LoginResponseDto(
String token
-) implements Serializable {
+) {
}
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
index 066472b8..710961ee 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
@@ -60,8 +60,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto)
throw new UserAlreadyExistsError("Email is already taken!");
}
}
-
- @Cacheable (value = "login-cache", key = "#loginRequestDto.email()")
+
@Override
public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception {
User user = userRepository.findByEmail(loginRequestDto.email())
From b2242e37fe43da49569205a854898ac06b8ec16a Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Thu, 5 Sep 2024 22:35:06 +0200
Subject: [PATCH 09/23] chore: added key - value pairs to the cacheable and
cacheevict annotations
---
.../backend/services/user/UserServiceImpl.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
index 710961ee..a21a0a15 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
@@ -60,7 +60,7 @@ public RegisterResponseDto register(RegisterRequestDto registerRequestDto)
throw new UserAlreadyExistsError("Email is already taken!");
}
}
-
+
@Override
public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception {
User user = userRepository.findByEmail(loginRequestDto.email())
@@ -73,7 +73,7 @@ public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception
return new LoginResponseDto(authService.generateToken(user));
}
- @CacheEvict
+ @CacheEvict(value = "update-profile-cache", key = "#email")
@Override
public ProfileUpdateResponseDto profileUpdate(
String email,
@@ -96,7 +96,7 @@ public ProfileUpdateResponseDto profileUpdate(
return new ProfileUpdateResponseDto(authService.generateToken(updatedUser));
}
- @Cacheable
+ @Cacheable(value = "profile-cache", key = "#username")
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository.findByEmail(username)
@@ -106,7 +106,7 @@ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundEx
/**
* Delete the user by username.
*/
- @CacheEvict
+ @CacheEvict(value = "delete-cache", key = "#username")
@Transactional
@Override
public void deleteProfile(String username) {
From b0fc8b1ef99f1fd32a53824b8451c1d549035302 Mon Sep 17 00:00:00 2001
From: Anna Ugrai
Date: Thu, 5 Sep 2024 22:56:22 +0200
Subject: [PATCH 10/23] chore: add cache dependencies to test app properties
---
backend/src/test/resources/application.properties | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/backend/src/test/resources/application.properties b/backend/src/test/resources/application.properties
index ba4ed94d..195fa5c5 100644
--- a/backend/src/test/resources/application.properties
+++ b/backend/src/test/resources/application.properties
@@ -23,4 +23,9 @@ spring.mail.properties.mail.smtp.starttls.enable=true
cors.urls=${CORS_URLS:http://localhost:5173}
# Where the verification link will redirect
-email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
\ No newline at end of file
+email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
+
+# Redis configuration
+spring.data.redis.host=${CACHE_URL:localhost}
+spring.data.redis.port=${CACHE_PORT:6379}
+spring.cache.type=none
\ No newline at end of file
From 7d302d040831b3a82388d8018898fd79f22cd3b9 Mon Sep 17 00:00:00 2001
From: markkovari
Date: Fri, 6 Sep 2024 10:34:44 +0200
Subject: [PATCH 11/23] chore: make redis connection conditional
---
.../backend/config/RedisConfig.java | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java b/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
index 899e6f40..2a1cc2db 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/config/RedisConfig.java
@@ -1,5 +1,7 @@
package com.greenfoxacademy.backend.config;
+import java.time.Duration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -9,23 +11,28 @@
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
-import java.time.Duration;
-
/**
* RedisConfig is a configuration class that defines the cache management strategy
* for Redis in the Spring Boot application. It configures the Redis Cache Manager
* and sets key serialization and expiration policies.
*/
-
@Configuration
+@ConditionalOnProperty(name = "spring.cache.type", havingValue = "redis")
public class RedisConfig {
+ /**
+ * The cacheManager method creates a RedisCacheManager bean that is used to manage.
+ */
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(3)) // Set TTL to 5 minutes
.disableCachingNullValues()
- .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
+ .serializeKeysWith(
+ RedisSerializationContext
+ .SerializationPair
+ .fromSerializer(new StringRedisSerializer())
+ );
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(cacheConfig)
From 0851821ef900b52dc63f08a9183002a30c6f1caf Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 09:24:30 +0200
Subject: [PATCH 12/23] chore: add password for redis cache
---
backend/src/main/resources/application.properties | 1 +
backend/src/test/resources/application.properties | 2 --
docker-compose.yaml | 5 ++++-
frontend/Dockerfile | 2 +-
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 8482850c..51376b05 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -30,4 +30,5 @@ email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
# Redis configuration
spring.data.redis.host=${CACHE_URL:localhost}
spring.data.redis.port=${CACHE_PORT:6379}
+spring.data.redis.password=${CACHE_PASSWORD}
spring.cache.type=redis
diff --git a/backend/src/test/resources/application.properties b/backend/src/test/resources/application.properties
index 195fa5c5..9e400d71 100644
--- a/backend/src/test/resources/application.properties
+++ b/backend/src/test/resources/application.properties
@@ -26,6 +26,4 @@ cors.urls=${CORS_URLS:http://localhost:5173}
email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
# Redis configuration
-spring.data.redis.host=${CACHE_URL:localhost}
-spring.data.redis.port=${CACHE_PORT:6379}
spring.cache.type=none
\ No newline at end of file
diff --git a/docker-compose.yaml b/docker-compose.yaml
index ae76a93b..f4c306c5 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -11,7 +11,9 @@ services:
POSTGRES_DB: petclinic_db
redis-cache:
- image: redis
+ image: bitnami/redis
+ environment:
+ - REDIS_PASSWORD=some_redis_password
ports:
- 6379:6379
@@ -35,6 +37,7 @@ services:
- CORS_URLS=http://localhost:5173
- CACHE_PORT=6379
- CACHE_URL=redis://redis-cache
+ - CACHE_PASSWORD=some_redis_password
depends_on:
- postgres-db
- redis-cache
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
index 48d50621..de382f6f 100644
--- a/frontend/Dockerfile
+++ b/frontend/Dockerfile
@@ -1,5 +1,5 @@
#create frontend container
-FROM node:lts as builder
+FROM node:lts AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
From 0f2750962f1b861296747e04fb2ff6ffe6f6f777 Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 09:33:26 +0200
Subject: [PATCH 13/23] chore: add dotenv file to store secrets
---
.env.sample | 2 ++
.gitignore | 1 +
README.md | 13 +++++++++++++
3 files changed, 16 insertions(+)
create mode 100644 .env.sample
diff --git a/.env.sample b/.env.sample
new file mode 100644
index 00000000..21df91ba
--- /dev/null
+++ b/.env.sample
@@ -0,0 +1,2 @@
+MAIL_PASSWORD=
+MAIL_USERNAME=
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f13774e4..28ebe5ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ data
*.idea
.DS_Store
+.env
\ No newline at end of file
diff --git a/README.md b/README.md
index c655d596..a7809a97 100644
--- a/README.md
+++ b/README.md
@@ -6,3 +6,16 @@
You can find the frontend of the project in the `frontend` folder
[here](./frontend/README.md).
+
+
+## Environemnts and secrets
+
+The project uses a `.env` file to store the secrets and environment variables. You can find an example of the file in the `.env.example` file. The dotenv file is used to store the secrets and environment variables for the docker-compose file.
+
+You can copy the sample file to a new file called `.env` and fill in the values.
+
+```bash
+cp .env.example .env
+```
+
+then fill in the values in the `.env` file.
From 710241851eebec3ae015a04008f3d221793bc5c0 Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 09:46:55 +0200
Subject: [PATCH 14/23] chore: add FeatureFlags config
---
.../greenfoxacademy/backend/config/FeatureFlags.java | 10 ++++++++++
1 file changed, 10 insertions(+)
create mode 100644 backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java b/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
new file mode 100644
index 00000000..33a7ca2a
--- /dev/null
+++ b/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
@@ -0,0 +1,10 @@
+package com.greenfoxacademy.backend.config;
+
+import lombok.Getter;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@Getter
+public class FeatureFlags {
+
+}
\ No newline at end of file
From d03e1bb65c0257d53903a0bbf30b88b48e437edc Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 10:09:37 +0200
Subject: [PATCH 15/23] add: feature flag to disable emailverification process
---
.../backend/config/FeatureFlags.java | 6 +++-
.../services/mail/EmailServiceImpl.java | 1 +
.../services/user/UserServiceImpl.java | 30 +++++++++++--------
.../src/main/resources/application.properties | 5 +++-
.../services/user/UserServiceImplTest.java | 14 ++++++++-
.../src/test/resources/application.properties | 5 +++-
docker-compose.yaml | 1 +
7 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java b/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
index 33a7ca2a..d6b90e71 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
@@ -1,10 +1,14 @@
package com.greenfoxacademy.backend.config;
import lombok.Getter;
+
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
-@Configuration
@Getter
+@Configuration
public class FeatureFlags {
+ @Value("${features.emailVerificationEnabled}")
+ private boolean emailVerificationEnabled;
}
\ No newline at end of file
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/mail/EmailServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/mail/EmailServiceImpl.java
index 48b59fc7..b2044b9e 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/services/mail/EmailServiceImpl.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/services/mail/EmailServiceImpl.java
@@ -6,6 +6,7 @@
import jakarta.mail.internet.MimeMessage;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
+
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
index 9a1c5602..b18a1380 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
@@ -1,5 +1,6 @@
package com.greenfoxacademy.backend.services.user;
+import com.greenfoxacademy.backend.config.FeatureFlags;
import com.greenfoxacademy.backend.dtos.LoginRequestDto;
import com.greenfoxacademy.backend.dtos.LoginResponseDto;
import com.greenfoxacademy.backend.dtos.ProfileUpdateRequestDto;
@@ -13,7 +14,9 @@
import com.greenfoxacademy.backend.services.auth.AuthService;
import com.greenfoxacademy.backend.services.mail.EmailService;
import jakarta.transaction.Transactional;
+
import java.util.UUID;
+
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@@ -30,34 +33,37 @@ public class UserServiceImpl implements UserService {
private final PasswordEncoder passwordEncoder;
private final AuthService authService;
private final EmailService emailService;
+ private final FeatureFlags featureFlags;
@Override
public RegisterResponseDto register(RegisterRequestDto registerRequestDto)
throws UserAlreadyExistsError {
+ boolean isEmailEnabled = featureFlags.isEmailVerificationEnabled();
+ UUID verificationId = isEmailEnabled ? UUID.randomUUID() : null;
// @formatter:off
User user = User.builder()
.email(registerRequestDto.email())
.firstName(registerRequestDto.firstName())
.lastName(registerRequestDto.lastName())
.password(passwordEncoder.encode(registerRequestDto.password()))
- .verificationId(UUID.randomUUID())
+ .verificationId(verificationId)
.build();
// @formatter:on
try {
User saved = userRepository.save(user);
- emailService.sendRegistrationEmail(
- saved.getEmail(),
- saved.getFirstName(),
- saved.getVerificationId()
- );
+ if (isEmailEnabled) {
+ emailService.sendRegistrationEmail(
+ saved.getEmail(),
+ saved.getFirstName(),
+ saved.getVerificationId());
+ }
return new RegisterResponseDto(saved.getId());
} catch (Exception e) {
throw new UserAlreadyExistsError("Email is already taken!");
}
}
-
@Override
public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception {
User user = userRepository.findByEmail(loginRequestDto.email())
@@ -73,14 +79,11 @@ public LoginResponseDto login(LoginRequestDto loginRequestDto) throws Exception
@Override
public ProfileUpdateResponseDto profileUpdate(
String email,
- ProfileUpdateRequestDto profileUpdateRequestDto
- ) throws CannotUpdateUserException {
+ ProfileUpdateRequestDto profileUpdateRequestDto) throws CannotUpdateUserException {
User user = userRepository.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
- if (
- userRepository.existsByEmail(profileUpdateRequestDto.email())
- && !email.equals(profileUpdateRequestDto.email())
- ) {
+ if (userRepository.existsByEmail(profileUpdateRequestDto.email())
+ && !email.equals(profileUpdateRequestDto.email())) {
throw new CannotUpdateUserException("Email is already taken!");
}
user.setEmail(profileUpdateRequestDto.email());
@@ -111,6 +114,7 @@ public void deleteProfile(String username) {
* Verify the user by id sent as email.
*/
public void verifyUser(UUID id) {
+ if (!featureFlags.isEmailVerificationEnabled()) return;
User userWithId = userRepository.findByVerificationId(id).orElseThrow();
userWithId.setVerificationId(null);
userRepository.save(userWithId);
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 4bdc3553..dacd8d92 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -25,4 +25,7 @@ spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
# Where the verification link will redirect
-email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
\ No newline at end of file
+email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
+
+# Feature Flags
+features.emailVerificationEnabled=${FEATURE_EMAIL_VERIFICATION_ENABLED:true}
diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java
index b6b7d4b8..ace03a8a 100644
--- a/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java
+++ b/backend/src/test/java/com/greenfoxacademy/backend/services/user/UserServiceImplTest.java
@@ -4,6 +4,7 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
+import com.greenfoxacademy.backend.config.FeatureFlags;
import com.greenfoxacademy.backend.dtos.LoginRequestDto;
import com.greenfoxacademy.backend.dtos.ProfileUpdateRequestDto;
import com.greenfoxacademy.backend.dtos.RegisterRequestDto;
@@ -13,8 +14,10 @@
import com.greenfoxacademy.backend.repositories.UserRepository;
import com.greenfoxacademy.backend.services.auth.AuthService;
import com.greenfoxacademy.backend.services.mail.EmailService;
+
import java.util.Optional;
import java.util.UUID;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -23,6 +26,7 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@@ -39,12 +43,19 @@ class UserServiceImplTest {
private AuthService authService;
@Mock
private EmailService emailService;
+ @Mock
+ private FeatureFlags featureFlags;
@BeforeEach
void setUp() {
Mockito.reset(userRepository);
- userService = new UserServiceImpl(userRepository, passwordEncoder, authService, emailService);
+ userService = new UserServiceImpl(
+ userRepository,
+ passwordEncoder,
+ authService,
+ emailService,
+ featureFlags);
}
@DisplayName("Register a new user if email not taken")
@@ -214,6 +225,7 @@ void loadUserByUsername() {
@Test
void verifyUserById() {
+ when(featureFlags.isEmailVerificationEnabled()).thenReturn(true);
UUID id = UUID.randomUUID();
User user = User.builder()
.id(1)
diff --git a/backend/src/test/resources/application.properties b/backend/src/test/resources/application.properties
index ba4ed94d..b3e490db 100644
--- a/backend/src/test/resources/application.properties
+++ b/backend/src/test/resources/application.properties
@@ -23,4 +23,7 @@ spring.mail.properties.mail.smtp.starttls.enable=true
cors.urls=${CORS_URLS:http://localhost:5173}
# Where the verification link will redirect
-email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
\ No newline at end of file
+email.baseUrl=${EMAIL_BASEURL:http://localhost:8080}
+
+# Feature Flags
+features.emailVerificationEnabled=${FEATURE_EMAIL_VERIFICATION_ENABLED:true}
diff --git a/docker-compose.yaml b/docker-compose.yaml
index c29112e5..ec69b6f5 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -28,5 +28,6 @@ services:
- DATABASE_USER=petclinic_db_user
- DATABASE_PASSWORD=petclinic_db_password
- CORS_URLS=http://localhost:5173
+ - FEATURE_EMAIL_VERIFICATION_ENABLED=false
depends_on:
- postgres-db
From 7a313a33d691fb69799f3e2b739d16c998eb7fa4 Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 10:18:49 +0200
Subject: [PATCH 16/23] fix: checkstyle issues
---
.../com/greenfoxacademy/backend/config/FeatureFlags.java | 7 ++++++-
.../backend/services/user/UserServiceImpl.java | 4 +++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java b/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
index d6b90e71..a89f63c6 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/config/FeatureFlags.java
@@ -1,14 +1,19 @@
package com.greenfoxacademy.backend.config;
import lombok.Getter;
-
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
+/**
+ * Configuration class for feature flags.
+ */
@Getter
@Configuration
public class FeatureFlags {
+ /**
+ * Flag to enable email verification.
+ */
@Value("${features.emailVerificationEnabled}")
private boolean emailVerificationEnabled;
}
\ No newline at end of file
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
index 883ed057..937de714 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/services/user/UserServiceImpl.java
@@ -119,7 +119,9 @@ public void deleteProfile(String username) {
* Verify the user by id sent as email.
*/
public void verifyUser(UUID id) {
- if (!featureFlags.isEmailVerificationEnabled()) return;
+ if (!featureFlags.isEmailVerificationEnabled()) {
+ return;
+ }
User userWithId = userRepository.findByVerificationId(id).orElseThrow();
userWithId.setVerificationId(null);
userRepository.save(userWithId);
From b7d780ed3e0c329983efc31ae4b25db46d8c1b29 Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 10:28:19 +0200
Subject: [PATCH 17/23] chore: add documentation for feature
---
README.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/README.md b/README.md
index c655d596..05663a1e 100644
--- a/README.md
+++ b/README.md
@@ -6,3 +6,9 @@
You can find the frontend of the project in the `frontend` folder
[here](./frontend/README.md).
+
+### Feature toggles
+
+| Feature | Description | Environment Variable | Default |
+| ------------------- | -------------------------------------- | ---------------------------------- | ------- |
+| email verificiation | Email verification during registration | FEATURE_EMAIL_VERIFICATION_ENABLED | false |
From b5f12fe6c0b16c1cdbc688f841d5d1dffcc8ae56 Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 11:02:31 +0200
Subject: [PATCH 18/23] refactor: protectedpage on frontend
---
frontend/src/pages/utils/ProtectedPage.tsx | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/frontend/src/pages/utils/ProtectedPage.tsx b/frontend/src/pages/utils/ProtectedPage.tsx
index 1d3842d5..0e09090a 100644
--- a/frontend/src/pages/utils/ProtectedPage.tsx
+++ b/frontend/src/pages/utils/ProtectedPage.tsx
@@ -1,16 +1,15 @@
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 <>{children}>;
+ if (!user) {
+ return ;
}
- return ;
+ return <>{children}>;
};
export { ProtectedPage };
From 6ad9ba90bd942d0dcb435e1f963c1d348246725a Mon Sep 17 00:00:00 2001
From: AnnaUgrai <149159395+AnnaUgrai@users.noreply.github.com>
Date: Sat, 7 Sep 2024 12:36:13 +0200
Subject: [PATCH 19/23] Update README.md
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Márk Kővári
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a7809a97..00802f87 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ The project uses a `.env` file to store the secrets and environment variables. Y
You can copy the sample file to a new file called `.env` and fill in the values.
```bash
-cp .env.example .env
+cp .env.sample .env
```
then fill in the values in the `.env` file.
From 24b6344445806142bce3342598b1318afcbe81aa Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 12:21:29 +0200
Subject: [PATCH 20/23] fix: make buttons visible
---
frontend/src/pages/Login.tsx | 6 ++++--
frontend/src/pages/ProfileDeletion.tsx | 10 +++++-----
frontend/src/pages/ProfileDetail.tsx | 5 +++--
frontend/src/pages/ProfileUpdate.tsx | 9 ++++++---
frontend/src/pages/Register.tsx | 6 ++++--
5 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx
index 30c2971c..f4d77f34 100644
--- a/frontend/src/pages/Login.tsx
+++ b/frontend/src/pages/Login.tsx
@@ -1,4 +1,4 @@
-import { useToast } from "@chakra-ui/react";
+import { Button, useToast } from "@chakra-ui/react";
import type { ChangeEvent, FormEvent } from "react";
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
@@ -67,7 +67,9 @@ export function Login() {
autoComplete="current-password"
required={true}
/>
-
+
Main
diff --git a/frontend/src/pages/ProfileDeletion.tsx b/frontend/src/pages/ProfileDeletion.tsx
index b10aaff1..ef3f8583 100644
--- a/frontend/src/pages/ProfileDeletion.tsx
+++ b/frontend/src/pages/ProfileDeletion.tsx
@@ -1,4 +1,4 @@
-import { useToast } from "@chakra-ui/react";
+import { Button, useToast } from "@chakra-ui/react";
import { useNavigate } from "react-router-dom";
import { deleteProfile } from "../httpClient.ts";
import { usePetClinicState } from "../state.ts";
@@ -44,21 +44,21 @@ export function ProfileDeletion() {
profile? We're sad to see you go! Please remember, this action is
permanent and you'll lose all your data."
-
-
>
);
}
diff --git a/frontend/src/pages/ProfileDetail.tsx b/frontend/src/pages/ProfileDetail.tsx
index bfda1e5f..40b2a8e6 100644
--- a/frontend/src/pages/ProfileDetail.tsx
+++ b/frontend/src/pages/ProfileDetail.tsx
@@ -1,3 +1,4 @@
+import { Button } from "@chakra-ui/react";
import { Link, useNavigate } from "react-router-dom";
import { usePetClinicState } from "../state.ts";
@@ -27,13 +28,13 @@ export function ProfileDetail() {
Profile update
- navigate("/delete-profile")}
>
Delete Profile
-
+
>
);
}
diff --git a/frontend/src/pages/ProfileUpdate.tsx b/frontend/src/pages/ProfileUpdate.tsx
index d141a901..bd400fa5 100644
--- a/frontend/src/pages/ProfileUpdate.tsx
+++ b/frontend/src/pages/ProfileUpdate.tsx
@@ -1,3 +1,4 @@
+import { Button } from "@chakra-ui/react";
import type { ChangeEvent, FormEvent } from "react";
import { PasswordStrengthValidator } from "../components/PasswordStrengthValidator";
import {
@@ -71,10 +72,12 @@ export function ProfileUpdate() {
required={true}
/>
- Save
- navigate("/")}>
+
+ Save
+
+ navigate("/")}>
Discard
-
+
>
);
diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx
index bdd44cf0..17555d06 100644
--- a/frontend/src/pages/Register.tsx
+++ b/frontend/src/pages/Register.tsx
@@ -1,4 +1,4 @@
-import { useToast } from "@chakra-ui/react";
+import { Button, useToast } from "@chakra-ui/react";
import type { ChangeEvent, FormEvent } from "react";
import { useState } from "react";
import { Link } from "react-router-dom";
@@ -90,7 +90,9 @@ function Register() {
onChange={handleUserChange}
/>
- Register
+
+ Register
+
Login
From 37d8351ee48e30bb126cd6563fc39a2b9937aa2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?=
Date: Sat, 7 Sep 2024 04:16:52 -0700
Subject: [PATCH 21/23] Update frontend/src/pages/ProfileDeletion.tsx
---
frontend/src/pages/ProfileDeletion.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/pages/ProfileDeletion.tsx b/frontend/src/pages/ProfileDeletion.tsx
index 72074984..6bc835b6 100644
--- a/frontend/src/pages/ProfileDeletion.tsx
+++ b/frontend/src/pages/ProfileDeletion.tsx
@@ -29,7 +29,7 @@ export function ProfileDeletion() {
} catch (error) {
if (error instanceof AxiosError) {
toast({
- title: "Cannot login 🫣.",
+ title: "Cannot delete profile 🫣.",
description:
error.response?.data.error ||
"Unknown network error, please contact support.",
From a307fd7cfeae38df7223cd9ec087b4aaa371a06d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A1rk=20K=C5=91v=C3=A1ri?=
Date: Sat, 7 Sep 2024 04:16:58 -0700
Subject: [PATCH 22/23] Update frontend/src/pages/Register.tsx
---
frontend/src/pages/Register.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx
index c1a1bcb1..cdd506d5 100644
--- a/frontend/src/pages/Register.tsx
+++ b/frontend/src/pages/Register.tsx
@@ -42,7 +42,7 @@ function Register() {
} catch (error) {
if (error instanceof AxiosError) {
toast({
- title: "Cannot login 🫣.",
+ title: "Cannot register 🫣.",
description:
error.response?.data.error ||
"Unknown network error, please contact support.",
From 69b8f08eabc438a38e3f831ac3541707cce204d3 Mon Sep 17 00:00:00 2001
From: markkovari
Date: Sat, 7 Sep 2024 15:04:14 +0200
Subject: [PATCH 23/23] fix: imports
---
.../src/main/java/com/greenfoxacademy/backend/models/Pet.java | 2 --
.../backend/services/user/OwnerServiceImplTest.java | 2 --
2 files changed, 4 deletions(-)
diff --git a/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java b/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java
index 791ff3d6..6fd1d341 100644
--- a/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java
+++ b/backend/src/main/java/com/greenfoxacademy/backend/models/Pet.java
@@ -8,9 +8,7 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
-
import java.util.Date;
-
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
diff --git a/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java
index 4fba12ec..bcdde253 100644
--- a/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java
+++ b/backend/src/test/java/com/greenfoxacademy/backend/services/user/OwnerServiceImplTest.java
@@ -17,7 +17,6 @@
import com.greenfoxacademy.backend.services.user.owner.OwnerServiceImpl;
import java.util.Optional;
import java.util.UUID;
-
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -26,7 +25,6 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;